diff --git a/core/assets/bundles/bundle.properties b/core/assets/bundles/bundle.properties index 279bbb7bbd..a0aea04348 100644 --- a/core/assets/bundles/bundle.properties +++ b/core/assets/bundles/bundle.properties @@ -2326,7 +2326,7 @@ lst.setprop = Sets a property of a unit or building. lst.effect = Create a particle effect. lst.sync = Sync a variable across the network.\nLimited to 20 times a second per variable. lst.makemarker = Create a new logic marker in the world.\nAn ID to identify this marker must be provided.\nMarkers currently limited to 20,000 per world. -lst.setmarker = Set a property for a marker.\nThe ID used must be the same as in the Make Marker instruction.\n[accent]null []values are being ignored instead of converting to 0. +lst.setmarker = Set a property for a marker.\nThe ID used must be the same as in the Make Marker instruction.\n[accent]null []values are ignored. lst.localeprint = Add map locale property value to the text buffer.\nTo set map locale bundles in map editor, check [accent]Map Info > Locale Bundles[].\nIf client is a mobile device, tries to print a property ending in ".mobile" first. logic.nounitbuild = [red]Unit building logic is not allowed here. diff --git a/core/src/mindustry/core/GameState.java b/core/src/mindustry/core/GameState.java index 5d9ee3515e..7c89abe05d 100644 --- a/core/src/mindustry/core/GameState.java +++ b/core/src/mindustry/core/GameState.java @@ -1,11 +1,9 @@ package mindustry.core; import arc.*; -import arc.struct.*; import arc.util.*; import mindustry.game.EventType.*; import mindustry.game.*; -import mindustry.game.MapObjectives.*; import mindustry.gen.*; import mindustry.maps.*; import mindustry.type.*; @@ -35,7 +33,7 @@ public class GameState{ /** Statistics for this save/game. Displayed after game over. */ public GameStats stats = new GameStats(); /** Markers not linked to objectives. Controlled by world processors. */ - public IntMap markers = new IntMap<>(); + public MapMarkers markers = new MapMarkers(); /** Locale-specific string bundles of current map */ public MapLocales mapLocales = new MapLocales(); /** Global attributes of the environment, calculated by weather. */ diff --git a/core/src/mindustry/core/Renderer.java b/core/src/mindustry/core/Renderer.java index a7fe83e6c2..13b1ead08f 100644 --- a/core/src/mindustry/core/Renderer.java +++ b/core/src/mindustry/core/Renderer.java @@ -375,13 +375,15 @@ public class Renderer implements ApplicationListener{ //draw objective markers state.rules.objectives.eachRunning(obj -> { for(var marker : obj.markers){ - if(!marker.minimap) marker.drawWorld(); + if(!marker.minimap){ + marker.drawWorld(); + } } }); - for(var marker : state.markers.values()){ - if(marker != null){ - if(!marker.isHidden() && !marker.minimap) marker.drawWorld(); + for(var marker : state.markers){ + if(!marker.isHidden() && !marker.minimap){ + marker.drawWorld(); } } diff --git a/core/src/mindustry/game/MapMarkers.java b/core/src/mindustry/game/MapMarkers.java new file mode 100644 index 0000000000..3afb6895ee --- /dev/null +++ b/core/src/mindustry/game/MapMarkers.java @@ -0,0 +1,72 @@ +package mindustry.game; + +import arc.struct.*; +import arc.util.*; +import mindustry.game.MapObjectives.*; +import mindustry.io.*; + +import java.io.*; +import java.util.*; + +public class MapMarkers implements Iterable{ + /** Maps marker unique ID to marker. */ + private IntMap map = new IntMap<>(); + /** Sequential list of markers. This allows for faster iteration than a map. */ + private Seq all = new Seq<>(false); + + public void add(int id, ObjectiveMarker marker){ + if(marker == null) return; + + var prev = map.put(id, marker); + if(prev != null){ + all.set(prev.arrayIndex, marker); + }else{ + all.add(marker); + marker.arrayIndex = all.size - 1; + } + } + + public void remove(int id){ + var prev = map.remove(id); + if(prev != null){ + if(all.size > prev.arrayIndex + 1){ //there needs to be something above the index to replace it with + all.remove(prev.arrayIndex); + //update its index + all.get(prev.arrayIndex).arrayIndex = prev.arrayIndex; + }else{ + //no sense updating the index of the replaced element when it was not replaced + all.remove(prev.arrayIndex); + } + } + } + + public @Nullable ObjectiveMarker get(int id){ + return map.get(id); + } + + public boolean has(int id){ + return get(id) != null; + } + + public int size(){ + return all.size; + } + + public void write(DataOutput stream) throws IOException{ + JsonIO.writeBytes(map, ObjectiveMarker.class, (DataOutputStream)stream); + } + + public void read(DataInput stream) throws IOException{ + all.clear(); + map = JsonIO.readBytes(IntMap.class, ObjectiveMarker.class, (DataInputStream)stream); + for(var entry : map.entries()){ + all.add(entry.value); + entry.value.arrayIndex = all.size - 1; + } + } + + @Override + public Iterator iterator(){ + return all.iterator(); + } +} diff --git a/core/src/mindustry/game/MapObjectives.java b/core/src/mindustry/game/MapObjectives.java index ee617ac49e..879ba2ad94 100644 --- a/core/src/mindustry/game/MapObjectives.java +++ b/core/src/mindustry/game/MapObjectives.java @@ -627,10 +627,11 @@ public class MapObjectives implements Iterable, Eachable, Eachable