|
1 | 1 | package fr.xpdustry.domination;
|
2 | 2 |
|
3 | 3 | import arc.*;
|
| 4 | +import arc.files.*; |
4 | 5 | import arc.struct.*;
|
5 | 6 | import arc.util.*;
|
| 7 | +import arc.util.serialization.*; |
| 8 | +import arc.util.serialization.JsonWriter.*; |
6 | 9 |
|
7 | 10 | import mindustry.content.*;
|
8 | 11 | import mindustry.game.*;
|
9 | 12 | import mindustry.game.EventType.*;
|
10 | 13 | import mindustry.gen.*;
|
11 | 14 | import mindustry.mod.Plugin;
|
12 | 15 |
|
| 16 | +import fr.xpdustry.domination.DominationSettings.*; |
| 17 | + |
13 | 18 | import java.util.*;
|
14 | 19 | import java.util.Map.*;
|
15 | 20 |
|
16 | 21 | import static arc.util.Log.*;
|
17 | 22 | import static mindustry.Vars.*;
|
18 | 23 |
|
19 |
| - |
20 |
| -@SuppressWarnings("unused") // <- Only used for this template so IntelliJ stop screaming at me... |
| 24 | +@SuppressWarnings("unused") |
21 | 25 | public class DominationPlugin extends Plugin{
|
22 |
| - private static int zoneRadius = 5; |
| 26 | + private static DominationSettings settings; |
23 | 27 |
|
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()); |
28 | 30 |
|
29 |
| - private static final Seq<Zone> zones = new Seq<>(); |
30 | 31 | 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 | + } |
32 | 43 |
|
33 | 44 | @Override
|
34 | 45 | 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 | + |
35 | 60 | 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)); |
40 | 69 | // Shows the zone center to the editors
|
41 | 70 | 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)); |
43 | 72 | });
|
44 | 73 | }
|
45 | 74 |
|
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))); |
49 | 79 |
|
| 80 | + // Gets the highest captured percent |
50 | 81 | float max = 0F;
|
51 | 82 | Team winner = Team.derelict;
|
52 |
| - |
53 | 83 | for(Entry<Team,Float> entry : teams.entrySet()){
|
54 | 84 | if(entry.getValue() > max){
|
55 | 85 | max = entry.getValue();
|
56 | 86 | winner = entry.getKey();
|
57 | 87 | }
|
58 | 88 | }
|
59 | 89 |
|
| 90 | + // Wee |
60 | 91 | Events.fire(new GameOverEvent(winner));
|
61 | 92 | Call.sendMessage(Strings.format("Congrats, @ team win!", winner));
|
62 | 93 | }
|
63 | 94 | }
|
64 | 95 | });
|
65 | 96 |
|
| 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 | + |
66 | 110 | Events.on(TapEvent.class, event -> {
|
67 | 111 | 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); |
69 | 113 | 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)); |
71 | 115 | }else{
|
72 |
| - zones.remove(zone); |
| 116 | + currentZones().remove(zone); |
73 | 117 | }
|
74 | 118 | }
|
75 | 119 | });
|
76 | 120 | }
|
77 | 121 |
|
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 |
| - */ |
82 | 122 | @Override
|
83 | 123 | 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 | + }); |
84 | 142 | }
|
85 | 143 |
|
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 |
| - */ |
90 | 144 | @Override
|
91 | 145 | 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..."); |
105 | 160 | }
|
| 161 | + default -> player.sendMessage(Strings.format("'@' is not a valid option.", args[0])); |
106 | 162 | }
|
107 | 163 | });
|
108 | 164 | }
|
|
0 commit comments