Skip to content

Commit 17290b1

Browse files
committed
1.0
1 parent 07b2ad7 commit 17290b1

File tree

5 files changed

+209
-51
lines changed

5 files changed

+209
-51
lines changed

build.gradle

+2-2
Original file line numberDiff line numberDiff line change
@@ -64,8 +64,8 @@ dependencies{
6464

6565

6666
compileJava{
67-
sourceCompatibility = JavaVersion.VERSION_1_8
68-
targetCompatibility = JavaVersion.VERSION_1_8
67+
sourceCompatibility = JavaVersion.VERSION_15
68+
targetCompatibility = JavaVersion.VERSION_15
6969
options.encoding = "UTF-8"
7070
}
7171

plugin.json

+2-2
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@
22
"name": "domination-plugin",
33
"displayName": "Xpdustry DominationPlugin",
44
"author": "Phinner",
5-
"description": "Dominate the field.",
6-
"version": "0.1",
5+
"description": "Capture the zones to win!",
6+
"version": "1.0",
77
"minGameVersion": "105",
88
"hidden": true,
99
"java": true,

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

+98-42
Original file line numberDiff line numberDiff line change
@@ -1,108 +1,164 @@
11
package fr.xpdustry.domination;
22

33
import arc.*;
4+
import arc.files.*;
45
import arc.struct.*;
56
import arc.util.*;
7+
import arc.util.serialization.*;
8+
import arc.util.serialization.JsonWriter.*;
69

710
import mindustry.content.*;
811
import mindustry.game.*;
912
import mindustry.game.EventType.*;
1013
import mindustry.gen.*;
1114
import mindustry.mod.Plugin;
1215

16+
import fr.xpdustry.domination.DominationSettings.*;
17+
1318
import java.util.*;
1419
import java.util.Map.*;
1520

1621
import static arc.util.Log.*;
1722
import static mindustry.Vars.*;
1823

19-
20-
@SuppressWarnings("unused") // <- Only used for this template so IntelliJ stop screaming at me...
24+
@SuppressWarnings("unused")
2125
public class DominationPlugin extends Plugin{
22-
private static int zoneRadius = 5;
26+
private static DominationSettings settings;
2327

24-
private static float captureRate = 10F;
25-
private static float updateTicks = Time.toSeconds;
26-
private static float renderTicks = Time.toSeconds / 6;
27-
private static float gameDuration = Time.toMinutes * 1;
28+
private static final Json json = new Json();
29+
private static final Fi config = new Fi(Core.files.external("domination-config.json").absolutePath());
2830

29-
private static final Seq<Zone> zones = new Seq<>();
3031
private static final Interval interval = new Interval(3);
31-
private static final ObjectSet<Player> editors = new ObjectSet<>();
32+
private static final ObjectSet<Playerc> editors = new ObjectSet<>();
33+
34+
static {
35+
json.setOutputType(OutputType.json);
36+
json.setSerializer(DominationSettings.class, new DominationIO());
37+
}
38+
39+
/** The zones of the current map, might throw a NPE if used when not playing */
40+
private Seq<Zone> currentZones(){
41+
return settings.maps.get(state.map.name(), Seq::new);
42+
}
3243

3344
@Override
3445
public void init(){
46+
// Settings
47+
if(config.exists()){
48+
settings = json.fromJson(DominationSettings.class, config);
49+
}else{
50+
settings = new DominationSettings();
51+
config.writeString(json.prettyPrint(settings));
52+
}
53+
54+
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
58+
});
59+
3560
Events.run(Trigger.update, () -> {
36-
if(state.rules.pvp){
37-
if(interval.get(0, updateTicks)) zones.forEach(z -> z.update(captureRate));
38-
if(interval.get(1, renderTicks)){
39-
zones.forEach(z -> z.render(updateTicks));
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));
4069
// Shows the zone center to the editors
4170
editors.each(p -> {
42-
zones.each(z -> Call.effect(p.con, Fx.heal, z.x * tilesize, z.y * tilesize, 0, z.getTeam().color));
71+
currentZones().each(z -> Call.effect(p.con(), Fx.heal, z.x * tilesize, z.y * tilesize, 0, z.getTeam().color));
4372
});
4473
}
4574

46-
if(interval.get(2, gameDuration)){
47-
Map<Team,Float> teams = new HashMap<>(state.teams.getActive().size);
48-
zones.each(zone -> teams.compute(zone.getTeam(), (t, i) -> zone.getPercent() + (i != null ? i : 0)));
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)));
4979

80+
// Gets the highest captured percent
5081
float max = 0F;
5182
Team winner = Team.derelict;
52-
5383
for(Entry<Team,Float> entry : teams.entrySet()){
5484
if(entry.getValue() > max){
5585
max = entry.getValue();
5686
winner = entry.getKey();
5787
}
5888
}
5989

90+
// Wee
6091
Events.fire(new GameOverEvent(winner));
6192
Call.sendMessage(Strings.format("Congrats, @ team win!", winner));
6293
}
6394
}
6495
});
6596

97+
// Reset the zones to their original states and save the settings
98+
Events.run(GameOverEvent.class, () -> {
99+
currentZones().each(Zone::reset);
100+
config.writeString(json.prettyPrint(settings));
101+
});
102+
103+
104+
Events.on(PlayerLeave.class, event -> {
105+
if(editors.contains(event.player)){
106+
editors.remove(event.player);
107+
}
108+
});
109+
66110
Events.on(TapEvent.class, event -> {
67111
if(editors.contains(event.player)){
68-
Zone zone = zones.find(z -> z.x == event.tile.x && z.y == event.tile.y);
112+
Zone zone = currentZones().find(z -> z.x == event.tile.x && z.y == event.tile.y);
69113
if(zone == null){
70-
zones.add(new Zone(event.tile.x, event.tile.y, zoneRadius));
114+
currentZones().add(new Zone(event.tile.x, event.tile.y, settings.zoneRadius));
71115
}else{
72-
zones.remove(zone);
116+
currentZones().remove(zone);
73117
}
74118
}
75119
});
76120
}
77121

78-
/**
79-
* This method is called when the game register the server-side commands.
80-
* Make sure your plugin don't load the commands twice by adding a simple boolean check.
81-
*/
82122
@Override
83123
public void registerServerCommands(CommandHandler handler){
124+
handler.register("domination-settings", "<save/load>", "Settings for the Domination plugin...", args -> {
125+
switch(args[0].toLowerCase()){
126+
case "save" -> {
127+
config.writeString(json.prettyPrint(settings));
128+
info("Settings have been successfully saved.");
129+
}
130+
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+
136+
settings = json.fromJson(DominationSettings.class, config);
137+
info("Settings have been successfully loaded.");
138+
}
139+
default -> info("The option '@' is invalid.", args[0].toLowerCase());
140+
}
141+
});
84142
}
85143

86-
/**
87-
* This method is called when the game register the client-side commands.
88-
* Make sure your plugin don't load the commands twice by adding a simple boolean check.
89-
*/
90144
@Override
91145
public void registerClientCommands(CommandHandler handler){
92-
handler.<Player>register("edit", "<on/off>", "edit the zones.", (args, player) -> {
93-
if(player.admin()){
94-
switch(args[0].toLowerCase()){
95-
case "on":
96-
editors.add(player);
97-
player.sendMessage("You enabled editor mode, now every click will create/delete a Zone.");
98-
break;
99-
case "off":
100-
editors.remove(player);
101-
player.sendMessage("You disabled editor mode, how unfortunate...");
102-
break;
103-
default:
104-
player.sendMessage(Strings.format("'@' is not a valid option, idiot!", args[0]));
146+
handler.<Playerc>register("domination-edit", "<on/off>", "edit the zones.", (args, player) -> {
147+
if(!player.admin()){
148+
player.sendMessage("[red]You need to be a chosen one to use this command.");
149+
return;
150+
}
151+
152+
switch(args[0].toLowerCase()){
153+
case "on" -> {
154+
editors.add(player);
155+
player.sendMessage("You enabled editor mode, now every click will create/delete a Zone.");
156+
}
157+
case "off" -> {
158+
editors.remove(player);
159+
player.sendMessage("You disabled editor mode, how unfortunate...");
105160
}
161+
default -> player.sendMessage(Strings.format("'@' is not a valid option.", args[0]));
106162
}
107163
});
108164
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
package fr.xpdustry.domination;
2+
3+
import arc.struct.*;
4+
import arc.util.*;
5+
import arc.util.serialization.*;
6+
import arc.util.serialization.Json.*;
7+
8+
9+
class DominationSettings{
10+
public int zoneRadius = 5;
11+
12+
public float
13+
captureRate = 10F,
14+
updateTicks = Time.toSeconds,
15+
renderTicks = Time.toSeconds / 6,
16+
gameDuration = Time.toMinutes * 5;
17+
18+
public final ObjectMap<String, Seq<Zone>> maps = new ObjectMap<>();
19+
20+
public static class DominationIO implements Serializer<DominationSettings>{
21+
@Override
22+
public void write(Json json, DominationSettings settings, Class aClass){
23+
json.writeObjectStart();
24+
25+
json.writeValue("zone-radius", settings.zoneRadius);
26+
json.writeValue("capture-rate", settings.captureRate);
27+
json.writeValue("update-ticks", settings.updateTicks);
28+
json.writeValue("render-ticks", settings.renderTicks);
29+
json.writeValue("game-duration", settings.gameDuration);
30+
31+
json.writeArrayStart("maps"); // map array begin
32+
settings.maps.each((map, zones) -> {
33+
json.writeObjectStart();
34+
json.writeValue("name", map);
35+
36+
json.writeArrayStart("zones"); // zone array begin
37+
zones.each(z -> json.writeValue(z.x + "," + z.y)); // zones pos are packed
38+
json.writeArrayEnd(); // zone array end
39+
40+
json.writeObjectEnd();
41+
});
42+
json.writeArrayEnd(); // map array end
43+
44+
json.writeObjectEnd();
45+
}
46+
47+
@Override
48+
public DominationSettings read(Json json, JsonValue jsonValue, Class aClass){
49+
var settings = new DominationSettings();
50+
51+
if(!jsonValue.isObject()){
52+
return settings;
53+
}
54+
55+
settings.zoneRadius = jsonValue.getInt( "zone-radius", settings.zoneRadius);
56+
settings.captureRate = jsonValue.getFloat( "capture-rate", settings.captureRate);
57+
settings.updateTicks = jsonValue.getFloat( "update-ticks", settings.updateTicks);
58+
settings.renderTicks = jsonValue.getFloat( "render-ticks", settings.renderTicks);
59+
settings.gameDuration = jsonValue.getFloat( "game-duration", settings.gameDuration);
60+
61+
JsonValue maps = jsonValue.get("maps");
62+
if(!maps.isArray()){
63+
return settings;
64+
}
65+
66+
for(var map : maps){
67+
if(!map.isObject()){
68+
continue;
69+
}
70+
71+
String name = map.getString("name");
72+
if(name == null) continue;
73+
settings.maps.put(name, new Seq<>(5));
74+
75+
var zones = map.get("zones");
76+
if(!zones.isArray()) continue;
77+
for(var zone : zones.asStringArray()){
78+
String[] pos = zone.split(",");
79+
if(pos.length != 2) continue;
80+
81+
try{
82+
settings.maps.get(name).add(new Zone(
83+
Integer.parseInt(pos[0].trim()),
84+
Integer.parseInt(pos[1].trim()),
85+
settings.zoneRadius
86+
));
87+
}catch(NumberFormatException ignored){
88+
}
89+
}
90+
}
91+
92+
return settings;
93+
}
94+
}
95+
}

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

+12-5
Original file line numberDiff line numberDiff line change
@@ -14,26 +14,27 @@
1414
import static mindustry.Vars.*;
1515

1616

17-
public class Zone {
17+
public class Zone{
1818
public final int x;
1919
public final int y;
2020

2121
private transient int radius;
2222
private transient float[] area;
2323

24-
private transient Team team = Team.derelict;
25-
private transient float percent = 100F;
24+
private transient Team team;
25+
private transient float percent;
2626
private transient final IntIntMap map;
2727

2828
private static final Seq<Effect> effects = Seq.with(Fx.mine, Fx.mineBig, Fx.mineHuge);
2929

3030
public Zone(int x, int y, int radius){
3131
this.x = x;
3232
this.y = y;
33-
setRadius(radius);
3433
// Generates a circle for rendering
35-
this.area = Geometry.regPoly((int)(this.radius * Mathf.pi), this.radius);
34+
setRadius(radius);
3635
this.map = new IntIntMap(state.teams.getActive().size);
36+
// Set the default values for a new game
37+
reset();
3738
}
3839

3940
public void update(float captureRate){
@@ -93,6 +94,12 @@ public float getPercent(){
9394
return percent;
9495
}
9596

97+
public void reset(){
98+
team = Team.derelict;
99+
percent = 100F;
100+
map.clear();
101+
}
102+
96103
@Override
97104
public String toString(){
98105
return "Zone{" + "x=" + x +

0 commit comments

Comments
 (0)