Skip to content

Commit 505b4e3

Browse files
committed
hotfix for xasmedy
1 parent 17290b1 commit 505b4e3

File tree

5 files changed

+187
-172
lines changed

5 files changed

+187
-172
lines changed

plugin.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
"displayName": "Xpdustry DominationPlugin",
44
"author": "Phinner",
55
"description": "Capture the zones to win!",
6-
"version": "1.0",
6+
"version": "1.1",
77
"minGameVersion": "105",
88
"hidden": true,
99
"java": true,
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
package fr.xpdustry.domination;
2+
3+
import arc.struct.*;
4+
import arc.util.serialization.*;
5+
import arc.util.serialization.Json.*;
6+
7+
import fr.xpdustry.domination.DominationPlugin.*;
8+
9+
10+
public class DominationIO implements Serializer<DominationSettings>{
11+
@Override
12+
public void write(Json json, DominationSettings settings, Class aClass){
13+
json.writeObjectStart();
14+
15+
json.writeValue("zone-radius", settings.zoneRadius);
16+
json.writeValue("capture-rate", settings.captureRate);
17+
json.writeValue("update-ticks", settings.updateTicks);
18+
json.writeValue("game-duration", settings.gameDuration);
19+
20+
json.writeArrayStart("maps"); // map array begin
21+
settings.maps.each((map, zones) -> {
22+
json.writeObjectStart();
23+
json.writeValue("name", map);
24+
25+
json.writeArrayStart("zones"); // zone array begin
26+
zones.each(z -> json.writeValue(z.x + ", " + z.y)); // zones pos are packed
27+
json.writeArrayEnd(); // zone array end
28+
29+
json.writeObjectEnd();
30+
});
31+
json.writeArrayEnd(); // map array end
32+
33+
json.writeObjectEnd();
34+
}
35+
36+
@Override
37+
public DominationSettings read(Json json, JsonValue jsonValue, Class aClass){
38+
var settings = new DominationSettings();
39+
40+
if(!jsonValue.isObject()){
41+
return settings;
42+
}
43+
44+
settings.zoneRadius = jsonValue.getInt( "zone-radius", settings.zoneRadius);
45+
settings.captureRate = jsonValue.getFloat( "capture-rate", settings.captureRate);
46+
settings.updateTicks = jsonValue.getFloat( "update-ticks", settings.updateTicks);
47+
settings.gameDuration = jsonValue.getFloat( "game-duration", settings.gameDuration);
48+
49+
JsonValue maps = jsonValue.get("maps");
50+
if(!maps.isArray()){
51+
return settings;
52+
}
53+
54+
for(var map : maps){
55+
if(!map.isObject()){
56+
continue;
57+
}
58+
59+
String name = map.getString("name");
60+
if(name == null) continue;
61+
settings.maps.put(name, new Seq<>(5));
62+
63+
var zones = map.get("zones");
64+
if(!zones.isArray()) continue;
65+
for(var zone : zones.asStringArray()){
66+
String[] pos = zone.split(",");
67+
if(pos.length != 2) continue;
68+
69+
try{
70+
settings.maps.get(name).add(new Zone(
71+
Integer.parseInt(pos[0].trim()),
72+
Integer.parseInt(pos[1].trim())
73+
));
74+
}catch(NumberFormatException ignored){
75+
}
76+
}
77+
}
78+
79+
return settings;
80+
}
81+
}

src/main/java/fr/xpdustry/domination/DominationPlugin.java

+97-44
Original file line numberDiff line numberDiff line change
@@ -2,41 +2,44 @@
22

33
import arc.*;
44
import arc.files.*;
5+
import arc.math.*;
6+
import arc.math.geom.*;
57
import arc.struct.*;
8+
import arc.struct.IntFloatMap.*;
69
import arc.util.*;
710
import arc.util.serialization.*;
811
import arc.util.serialization.JsonWriter.*;
912

1013
import mindustry.content.*;
14+
import mindustry.entities.*;
1115
import mindustry.game.*;
1216
import mindustry.game.EventType.*;
1317
import mindustry.gen.*;
1418
import mindustry.mod.Plugin;
1519

16-
import fr.xpdustry.domination.DominationSettings.*;
17-
18-
import java.util.*;
19-
import java.util.Map.*;
20+
import fr.xpdustry.domination.Zone.*;
2021

2122
import static arc.util.Log.*;
2223
import static mindustry.Vars.*;
2324

25+
2426
@SuppressWarnings("unused")
2527
public class DominationPlugin extends Plugin{
2628
private static DominationSettings settings;
27-
2829
private static final Json json = new Json();
2930
private static final Fi config = new Fi(Core.files.external("domination-config.json").absolutePath());
3031

3132
private static final Interval interval = new Interval(3);
3233
private static final ObjectSet<Playerc> editors = new ObjectSet<>();
3334

35+
private static final IntFloatMap leaderboard = new IntFloatMap();
36+
private static final Seq<Effect> effects = Seq.with(Fx.mine, Fx.mineBig, Fx.mineHuge);
37+
3438
static {
3539
json.setOutputType(OutputType.json);
3640
json.setSerializer(DominationSettings.class, new DominationIO());
3741
}
3842

39-
/** The zones of the current map, might throw a NPE if used when not playing */
4043
private Seq<Zone> currentZones(){
4144
return settings.maps.get(state.map.name(), Seq::new);
4245
}
@@ -51,46 +54,90 @@ public void init(){
5154
config.writeString(json.prettyPrint(settings));
5255
}
5356

57+
Events.run(PlayEvent.class, () -> {
58+
state.rules.modeName = "[red]Domination";
59+
});
60+
5461
Events.run(WorldLoadEvent.class, () -> {
55-
// updates the radius if it has been changed
56-
currentZones().each(z -> z.setRadius(settings.zoneRadius));
57-
interval.reset(2, 0); // Resets the timer when a new game begin
62+
interval.reset(2, 0); // Reset the timer
5863
});
5964

65+
// Main
6066
Events.run(Trigger.update, () -> {
61-
if(state.rules.pvp && !state.gameOver){
62-
if(interval.get(0, settings.updateTicks)){
63-
currentZones().forEach(z -> z.update(settings.captureRate));
64-
// Time remaining in seconds
65-
int time = (int) ((settings.gameDuration - interval.getTime(2)) / Time.toSeconds);
66-
Call.setHudText(Strings.format("Time remaining > @:@", time / 60, time % 60));
67-
}if(interval.get(1, settings.renderTicks)){
68-
currentZones().forEach(z -> z.render(settings.updateTicks));
69-
// Shows the zone center to the editors
70-
editors.each(p -> {
71-
currentZones().each(z -> Call.effect(p.con(), Fx.heal, z.x * tilesize, z.y * tilesize, 0, z.getTeam().color));
72-
});
67+
if(isActive() && interval.get(0, settings.updateTicks)){
68+
// Updates the zone internal data
69+
currentZones().each(z -> z.update(settings));
70+
71+
// Updates the leaderboard [team -> percent_captured]
72+
leaderboard.clear(state.teams.active.size + 1);
73+
currentZones().each(z -> leaderboard.increment(z.getTeam().id, 0, z.getPercent()));
74+
}
75+
76+
if(isActive() && interval.get(1, settings.gameDuration)){
77+
Entry winner = new Entry();
78+
for(Entry entry : leaderboard.entries()){
79+
if(entry.value > winner.value){
80+
winner = entry;
81+
}
7382
}
7483

75-
// Ugly way to determine the winner :^(
76-
if(interval.get(2, settings.gameDuration)){
77-
Map<Team,Float> teams = new HashMap<>(state.teams.getActive().size); // using map for the compute method...
78-
currentZones().each(zone -> teams.compute(zone.getTeam(), (t, i) -> zone.getPercent() + (i != null ? i : 0)));
79-
80-
// Gets the highest captured percent
81-
float max = 0F;
82-
Team winner = Team.derelict;
83-
for(Entry<Team,Float> entry : teams.entrySet()){
84-
if(entry.getValue() > max){
85-
max = entry.getValue();
86-
winner = entry.getKey();
84+
Events.fire(new GameOverEvent(Team.get(winner.key)));
85+
}
86+
87+
if(interval.get(2, Time.toSeconds / 6)){
88+
// HUD text
89+
StringBuilder builder = new StringBuilder(100);
90+
// Generate a circle for the zone rendering
91+
float[] circle = Geometry.regPoly((int)(Mathf.pi * settings.zoneRadius), settings.zoneRadius);
92+
93+
if(isActive()){
94+
currentZones().each(z -> {
95+
// Render the circle
96+
Geometry.iteratePolygon((cx, cy) -> {
97+
Call.effect(effects.random(), (cx + z.x) * tilesize, (cy + z.y) * tilesize, 0, z.getTeam().color);
98+
}, circle);
99+
100+
// Display the percent in the circles
101+
String percent = Strings.format("[#@]@%", z.getTeam().color, Strings.fixed(z.getPercent(), 0));
102+
Call.label(percent, 1.0F / 6, z.x * tilesize, z.y * tilesize);
103+
});
104+
105+
// Time remaining
106+
int time = (int) ((settings.gameDuration - interval.getTime(1)) / Time.toSeconds);
107+
builder.append(Strings.format("Time remaining > @\n", Strings.formatMillis(time * 1000L)));
108+
109+
// Leaderboard
110+
var iterator = leaderboard.entries().iterator();
111+
while(iterator.hasNext()){
112+
var entry = iterator.next();
113+
var team = Team.get(entry.key);
114+
if(team != Team.derelict){
115+
builder.append(Strings.format("[#@]@[] > @%", team.color, team.name, (int)entry.value));
116+
if(iterator.hasNext()) builder.append('\n');
87117
}
88118
}
89119

90-
// Wee
91-
Events.fire(new GameOverEvent(winner));
92-
Call.sendMessage(Strings.format("Congrats, @ team win!", winner));
120+
// Unclaimed zones
121+
if(leaderboard.containsKey(Team.derelict.id)){
122+
builder.append(Strings.format("\n[#@]Unclaimed[] > @%", Team.derelict.color, (int)leaderboard.get(Team.derelict.id)));
123+
}
124+
125+
Call.setHudText(builder.toString());
93126
}
127+
128+
// Rendering for editors
129+
editors.each(p -> {
130+
currentZones().each(z -> {
131+
Call.effect(p.con(), Fx.unitLand, z.x * tilesize, z.y * tilesize, 0, z.getTeam().color);
132+
133+
if(!state.rules.pvp && state.isGame()){
134+
// Render the circle
135+
Geometry.iteratePolygon((cx, cy) -> {
136+
Call.effect(p.con(), effects.random(), (cx + z.x) * tilesize, (cy + z.y) * tilesize, 0, z.getTeam().color);
137+
}, circle);
138+
}
139+
});
140+
});
94141
}
95142
});
96143

@@ -100,7 +147,6 @@ public void init(){
100147
config.writeString(json.prettyPrint(settings));
101148
});
102149

103-
104150
Events.on(PlayerLeave.class, event -> {
105151
if(editors.contains(event.player)){
106152
editors.remove(event.player);
@@ -111,7 +157,7 @@ public void init(){
111157
if(editors.contains(event.player)){
112158
Zone zone = currentZones().find(z -> z.x == event.tile.x && z.y == event.tile.y);
113159
if(zone == null){
114-
currentZones().add(new Zone(event.tile.x, event.tile.y, settings.zoneRadius));
160+
currentZones().add(new Zone(event.tile.x, event.tile.y));
115161
}else{
116162
currentZones().remove(zone);
117163
}
@@ -121,18 +167,13 @@ public void init(){
121167

122168
@Override
123169
public void registerServerCommands(CommandHandler handler){
124-
handler.register("domination-settings", "<save/load>", "Settings for the Domination plugin...", args -> {
170+
handler.register("domination-config", "<save/load>", "Settings for the Domination plugin...", args -> {
125171
switch(args[0].toLowerCase()){
126172
case "save" -> {
127173
config.writeString(json.prettyPrint(settings));
128174
info("Settings have been successfully saved.");
129175
}
130176
case "load" -> {
131-
if(state.isGame()){
132-
info("You can't just modify the settings in the middle of the game...");
133-
return;
134-
}
135-
136177
settings = json.fromJson(DominationSettings.class, config);
137178
info("Settings have been successfully loaded.");
138179
}
@@ -162,4 +203,16 @@ public void registerClientCommands(CommandHandler handler){
162203
}
163204
});
164205
}
206+
207+
public static boolean isActive(){
208+
return state.rules.pvp && !state.isMenu();
209+
}
210+
211+
static class DominationSettings{
212+
public int zoneRadius = 5;
213+
public float captureRate = 10F;
214+
public float updateTicks = Time.toSeconds;
215+
public float gameDuration = Time.toMinutes * 5;
216+
public final ObjectMap<String, Seq<Zone>> maps = new ObjectMap<>();
217+
}
165218
}

0 commit comments

Comments
 (0)