Skip to content

Commit 9463ca2

Browse files
committed
feat: Extracted capture progress to an interface
1 parent 23f9e46 commit 9463ca2

9 files changed

+162
-53
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
/*
2+
* HexedReloaded, A reimplementation of the hexed gamemode from Anuke, with more features and better performances.
3+
*
4+
* Copyright (C) 2024 Xpdustry
5+
*
6+
* This program is free software: you can redistribute it and/or modify
7+
* it under the terms of the GNU General Public License as published by
8+
* the Free Software Foundation, either version 3 of the License, or
9+
* (at your option) any later version.
10+
*
11+
* This program is distributed in the hope that it will be useful,
12+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+
* GNU General Public License for more details.
15+
*
16+
* You should have received a copy of the GNU General Public License
17+
* along with this program. If not, see <https://www.gnu.org/licenses/>.
18+
*/
19+
package com.xpdustry.hexed;
20+
21+
import arc.struct.IntFloatMap;
22+
import com.xpdustry.hexed.model.Hex;
23+
import mindustry.Vars;
24+
import mindustry.gen.Groups;
25+
import mindustry.world.blocks.storage.CoreBlock;
26+
27+
final class AnukeHexedCaptureProgress implements HexedCaptureProgress {
28+
29+
private final int requirement;
30+
31+
AnukeHexedCaptureProgress(final int requirement) {
32+
if (requirement <= 0) {
33+
throw new IllegalArgumentException("Requirement must be greater than 0");
34+
}
35+
this.requirement = requirement;
36+
}
37+
38+
@Override
39+
public void calculate(final Hex hex, final IntFloatMap capture) {
40+
Groups.unit
41+
.intersect(
42+
hex.getX() - hex.getRadius(),
43+
hex.getY() - hex.getRadius(),
44+
hex.getDiameter(),
45+
hex.getDiameter())
46+
.each(u -> {
47+
if (!u.isPlayer() && hex.contains(u.tileX(), u.tileY())) {
48+
capture.increment(u.team().id, u.health() / 10F);
49+
}
50+
});
51+
52+
for (int cx = hex.getTileX() - hex.getTileRadius(); cx < hex.getTileX() + hex.getTileRadius(); cx++) {
53+
for (int cy = hex.getTileY() - hex.getTileRadius(); cy < hex.getTileY() + hex.getTileRadius(); cy++) {
54+
final var tile = Vars.world.tile(cx, cy);
55+
if (tile != null && tile.synthetic() && hex.contains(tile.x, tile.y)) {
56+
if (tile.block() instanceof CoreBlock) {
57+
capture.increment(tile.team().id, 1F);
58+
} else if (tile.block().requirements != null) {
59+
for (final var stack : tile.block().requirements) {
60+
capture.increment(tile.team().id, stack.amount * stack.item.cost);
61+
}
62+
}
63+
}
64+
}
65+
}
66+
67+
final var keys = capture.keys();
68+
while (keys.hasNext()) {
69+
final var key = keys.next();
70+
capture.put(key, capture.get(key) / this.requirement);
71+
}
72+
}
73+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
/*
2+
* HexedReloaded, A reimplementation of the hexed gamemode from Anuke, with more features and better performances.
3+
*
4+
* Copyright (C) 2024 Xpdustry
5+
*
6+
* This program is free software: you can redistribute it and/or modify
7+
* it under the terms of the GNU General Public License as published by
8+
* the Free Software Foundation, either version 3 of the License, or
9+
* (at your option) any later version.
10+
*
11+
* This program is distributed in the hope that it will be useful,
12+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+
* GNU General Public License for more details.
15+
*
16+
* You should have received a copy of the GNU General Public License
17+
* along with this program. If not, see <https://www.gnu.org/licenses/>.
18+
*/
19+
package com.xpdustry.hexed;
20+
21+
import arc.struct.IntFloatMap;
22+
import com.xpdustry.hexed.model.Hex;
23+
24+
public interface HexedCaptureProgress {
25+
26+
static HexedCaptureProgress anuke(final int requirement) {
27+
return new AnukeHexedCaptureProgress(requirement);
28+
}
29+
30+
static HexedCaptureProgress anuke() {
31+
return new AnukeHexedCaptureProgress(210);
32+
}
33+
34+
void calculate(final Hex hex, final IntFloatMap capture);
35+
}

src/main/java/com/xpdustry/hexed/HexedCommands.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ public void onSpectateCommand(final CommandSender sender) {
131131
}
132132
}
133133

134-
@Command("hexed join")
134+
@Command("join")
135135
@CommandDescription("Join the game.")
136136
public void onJoinCommand(final CommandSender sender) {
137137
if (sender.isServer()) {

src/main/java/com/xpdustry/hexed/HexedLogic.java

+2-4
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@
3131
import com.xpdustry.hexed.event.HexPlayerJoinEvent;
3232
import com.xpdustry.hexed.event.HexPlayerQuitEvent;
3333
import com.xpdustry.hexed.event.HexedGameOverEvent;
34-
import java.time.Duration;
3534
import java.util.ArrayList;
3635
import java.util.Comparator;
3736
import java.util.List;
@@ -128,12 +127,11 @@ public void onBlockDestroy(final EventType.BlockDestroyEvent event) {
128127
@Override
129128
public void onPluginUpdate() {
130129
if (!this.hexed.isEnabled()) {
131-
this.hexed.getHexedState().setCounter(Duration.ZERO);
132130
return;
133-
} else {
134-
this.hexed.getHexedState().incrementCounter(Time.delta);
135131
}
136132

133+
this.hexed.getHexedState().incrementCounter(Time.delta);
134+
137135
if (this.interval.get(CONTROLLER_TIMER, 2 * 60)) {
138136
for (final var hex : this.hexed.getHexedState().getHexes()) {
139137
final var oldController = this.hexed.getHexedState().getController(hex);

src/main/java/com/xpdustry/hexed/HexedPluginReloaded.java

+20-1
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,13 @@
1818
*/
1919
package com.xpdustry.hexed;
2020

21+
import com.xpdustry.distributor.api.DistributorProvider;
22+
import com.xpdustry.distributor.api.annotation.PluginAnnotationProcessor;
2123
import com.xpdustry.distributor.api.plugin.AbstractMindustryPlugin;
24+
import com.xpdustry.distributor.api.plugin.PluginListener;
25+
import com.xpdustry.hexed.generation.AnukeHexedGenerator;
2226
import com.xpdustry.hexed.generation.HexedMapContext;
27+
import com.xpdustry.hexed.generation.HexedMapGenerator;
2328
import com.xpdustry.hexed.generation.MapGenerator;
2429
import com.xpdustry.hexed.generation.MapLoader;
2530
import mindustry.Vars;
@@ -28,6 +33,7 @@
2833
@SuppressWarnings("unused")
2934
public final class HexedPluginReloaded extends AbstractMindustryPlugin implements HexedAPI {
3035

36+
private final PluginAnnotationProcessor<?> processor = PluginAnnotationProcessor.events(this);
3137
private @MonotonicNonNull HexedStateImpl state = null;
3238

3339
@Override
@@ -51,7 +57,11 @@ public boolean start(final MapGenerator<HexedMapContext> generator) {
5157
final var start = System.currentTimeMillis();
5258
final var context = loader.load(generator);
5359
this.getLogger().info("Generated hexed map in {} milliseconds.", System.currentTimeMillis() - start);
54-
this.state = new HexedStateImpl(context.getBaseSchematic(), context.getHexes(), context.getDuration());
60+
this.state = new HexedStateImpl(
61+
context.getBaseSchematic(),
62+
context.getCaptureCalculator(),
63+
context.getHexes(),
64+
context.getDuration());
5565
return true;
5666
} catch (final Exception e) {
5767
this.getLogger().error("Failed to host a hexed game", e);
@@ -61,8 +71,17 @@ public boolean start(final MapGenerator<HexedMapContext> generator) {
6171

6272
@Override
6373
public void onInit() {
74+
DistributorProvider.get()
75+
.getServiceManager()
76+
.register(this, HexedMapGenerator.class, new AnukeHexedGenerator());
6477
this.addListener(new HexedLogic(this));
6578
this.addListener(new HexedRenderer(this));
6679
this.addListener(new HexedCommands(this));
6780
}
81+
82+
@Override
83+
protected void addListener(final PluginListener listener) {
84+
super.addListener(listener);
85+
this.processor.process(listener);
86+
}
6887
}

src/main/java/com/xpdustry/hexed/HexedStateImpl.java

+14-46
Original file line numberDiff line numberDiff line change
@@ -33,15 +33,10 @@
3333
import java.util.Set;
3434
import mindustry.Vars;
3535
import mindustry.game.Team;
36-
import mindustry.gen.Groups;
37-
import mindustry.world.blocks.storage.CoreBlock;
3836
import org.checkerframework.checker.nullness.qual.Nullable;
3937

4038
final class HexedStateImpl implements HexedState {
4139

42-
// Item requirement to capture a hex
43-
private static final int ITEM_REQUIREMENT = 210;
44-
4540
private final Map<Hex, Team> controllers = new HashMap<>();
4641
private final List<Hex> hexes;
4742
private final Set<Team> dying = new HashSet<>();
@@ -51,9 +46,15 @@ final class HexedStateImpl implements HexedState {
5146
private final Duration duration;
5247
private float counter = 0f;
5348
private final ImmutableSchematic base;
49+
private final HexedCaptureProgress calculator;
5450

55-
HexedStateImpl(final ImmutableSchematic base, final List<Hex> hexes, final Duration duration) {
51+
HexedStateImpl(
52+
final ImmutableSchematic base,
53+
final HexedCaptureProgress calculator,
54+
final List<Hex> hexes,
55+
final Duration duration) {
5656
this.base = base;
57+
this.calculator = calculator;
5758
this.duration = duration;
5859
this.hexes = List.copyOf(hexes);
5960
for (final var hex : this.hexes) {
@@ -146,54 +147,21 @@ public float getProgress(final Hex hex, final Team team) {
146147
}
147148

148149
private float getProgress0(final Hex hex, final Team team) {
149-
return (this.progress
150-
.get(Point2.pack(hex.getTileX(), hex.getTileY()), () -> new IntFloatMap(4))
151-
.get(team.id)
152-
/ ITEM_REQUIREMENT)
150+
return this.progress
151+
.get(Point2.pack(hex.getTileX(), hex.getTileY()), () -> new IntFloatMap(4))
152+
.get(team.id)
153153
* 100F;
154154
}
155155

156156
public void updateProgress(final Hex hex) {
157-
final var center = Vars.world.tile(hex.getTileX(), hex.getTileY());
158-
159-
if (center.block() instanceof CoreBlock) {
160-
this.controllers.put(hex, center.team());
161-
}
162-
163157
final var progress = this.progress.get(Point2.pack(hex.getTileX(), hex.getTileY()), () -> new IntFloatMap(4));
164158
progress.clear();
165-
Groups.unit
166-
.intersect(
167-
hex.getX() - hex.getRadius(),
168-
hex.getY() - hex.getRadius(),
169-
hex.getDiameter(),
170-
hex.getDiameter())
171-
.each(u -> {
172-
if (!u.isPlayer() && hex.contains(u.tileX(), u.tileY())) {
173-
progress.increment(u.team().id, u.health() / 10F);
174-
}
175-
});
176-
177-
for (int cx = hex.getTileX() - hex.getTileRadius(); cx < hex.getTileX() + hex.getTileRadius(); cx++) {
178-
for (int cy = hex.getTileY() - hex.getTileRadius(); cy < hex.getTileY() + hex.getTileRadius(); cy++) {
179-
final var tile = Vars.world.tile(cx, cy);
180-
if (tile != null
181-
&& tile.synthetic()
182-
&& hex.contains(tile.x, tile.y)
183-
&& tile.block().requirements != null) {
184-
for (final var stack : tile.block().requirements) {
185-
progress.increment(tile.team().id, stack.amount * stack.item.cost);
186-
}
187-
}
188-
}
189-
}
190-
159+
this.calculator.calculate(hex, progress);
191160
final var data = Vars.state.teams.getActive().max(t -> progress.get(t.team.id));
192-
if (data != null && progress.get(data.team.id) >= ITEM_REQUIREMENT) {
161+
if (data != null && progress.get(data.team.id) >= 1F) {
193162
this.controllers.put(hex, data.team);
194-
return;
163+
} else {
164+
this.controllers.put(hex, null);
195165
}
196-
197-
this.controllers.put(hex, null);
198166
}
199167
}

src/main/java/com/xpdustry/hexed/generation/AnukeHexedGenerator.java

-1
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,6 @@ public String getName() {
7575
return "anuke";
7676
}
7777

78-
@SuppressWarnings("ExtractMethodRecommender")
7978
@Override
8079
public HexedMapContext generate() {
8180
final var context = new SimpleHexedMapContext();

src/main/java/com/xpdustry/hexed/generation/HexedMapContext.java

+5
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
*/
1919
package com.xpdustry.hexed.generation;
2020

21+
import com.xpdustry.hexed.HexedCaptureProgress;
2122
import com.xpdustry.hexed.model.Hex;
2223
import java.time.Duration;
2324
import java.util.List;
@@ -44,6 +45,10 @@ public interface HexedMapContext extends MapContext {
4445

4546
void setBaseSchematic(final ImmutableSchematic schematic);
4647

48+
HexedCaptureProgress getCaptureCalculator();
49+
50+
void setCaptureCalculator(final HexedCaptureProgress calculator);
51+
4752
private static ImmutableSchematic loadDefaultBaseSchematic() {
4853
try (final var stream = SimpleHexedMapContext.class.getResourceAsStream("/com/xpdustry/hexed/default.msch")) {
4954
return new ImmutableSchematic(Schematics.read(Objects.requireNonNull(stream)));

src/main/java/com/xpdustry/hexed/generation/SimpleHexedMapContext.java

+12
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
*/
1919
package com.xpdustry.hexed.generation;
2020

21+
import com.xpdustry.hexed.HexedCaptureProgress;
2122
import com.xpdustry.hexed.model.Hex;
2223
import java.time.Duration;
2324
import java.util.Collections;
@@ -31,6 +32,7 @@ public class SimpleHexedMapContext extends SimpleMapContext implements HexedMapC
3132
private List<Hex> hexes = Collections.emptyList();
3233
private Duration duration = DEFAULT_GAME_DURATION;
3334
private ImmutableSchematic schematic = DEFAULT_BASE_SCHEMATIC;
35+
private HexedCaptureProgress calculator = HexedCaptureProgress.anuke();
3436

3537
{
3638
final var rules = this.getRules();
@@ -89,4 +91,14 @@ public ImmutableSchematic getBaseSchematic() {
8991
public void setBaseSchematic(final ImmutableSchematic schematic) {
9092
this.schematic = schematic;
9193
}
94+
95+
@Override
96+
public HexedCaptureProgress getCaptureCalculator() {
97+
return this.calculator;
98+
}
99+
100+
@Override
101+
public void setCaptureCalculator(final HexedCaptureProgress calculator) {
102+
this.calculator = calculator;
103+
}
92104
}

0 commit comments

Comments
 (0)