From 78215363dccd6ad013b7a3bc0fa5edfb3b4d50eb Mon Sep 17 00:00:00 2001 From: Anuken Date: Wed, 3 Jul 2019 09:50:33 -0400 Subject: [PATCH] Work on fixing entity ID mapping --- .../io/anuke/mindustry/content/TypeIDs.java | 18 +++ .../anuke/mindustry/core/ContentLoader.java | 17 +-- core/src/io/anuke/mindustry/core/Control.java | 5 - .../io/anuke/mindustry/core/NetClient.java | 5 +- .../io/anuke/mindustry/core/NetServer.java | 2 +- .../anuke/mindustry/entities/effect/Fire.java | 9 +- .../mindustry/entities/effect/Puddle.java | 6 + .../mindustry/entities/traits/TypeTrait.java | 4 + .../mindustry/entities/type/BaseUnit.java | 6 + .../anuke/mindustry/entities/type/Player.java | 9 +- core/src/io/anuke/mindustry/game/TypeID.java | 19 +++ .../io/anuke/mindustry/io/SaveVersion.java | 53 +++++++- .../io/versions/LegacyTypeTable.java | 118 ++++++++++++++++++ .../io/anuke/mindustry/type/ContentType.java | 3 +- .../src/io/anuke/mindustry/type/UnitType.java | 11 +- 15 files changed, 247 insertions(+), 38 deletions(-) create mode 100644 core/src/io/anuke/mindustry/content/TypeIDs.java create mode 100644 core/src/io/anuke/mindustry/game/TypeID.java create mode 100644 core/src/io/anuke/mindustry/io/versions/LegacyTypeTable.java diff --git a/core/src/io/anuke/mindustry/content/TypeIDs.java b/core/src/io/anuke/mindustry/content/TypeIDs.java new file mode 100644 index 0000000000..faf82ed359 --- /dev/null +++ b/core/src/io/anuke/mindustry/content/TypeIDs.java @@ -0,0 +1,18 @@ +package io.anuke.mindustry.content; + +import io.anuke.mindustry.entities.effect.Fire; +import io.anuke.mindustry.entities.effect.Puddle; +import io.anuke.mindustry.entities.type.Player; +import io.anuke.mindustry.game.ContentList; +import io.anuke.mindustry.game.TypeID; + +public class TypeIDs implements ContentList{ + public static TypeID fire, puddle, player; + + @Override + public void load(){ + fire = new TypeID("fire", Fire::new); + puddle = new TypeID("puddle", Puddle::new); + player = new TypeID("player", Player::new); + } +} diff --git a/core/src/io/anuke/mindustry/core/ContentLoader.java b/core/src/io/anuke/mindustry/core/ContentLoader.java index 1bf12ba4a3..6e085668f0 100644 --- a/core/src/io/anuke/mindustry/core/ContentLoader.java +++ b/core/src/io/anuke/mindustry/core/ContentLoader.java @@ -7,10 +7,6 @@ import io.anuke.arc.graphics.Pixmap; import io.anuke.arc.util.Log; import io.anuke.mindustry.content.*; import io.anuke.mindustry.entities.bullet.BulletType; -import io.anuke.mindustry.entities.effect.Fire; -import io.anuke.mindustry.entities.effect.Puddle; -import io.anuke.mindustry.entities.traits.TypeTrait; -import io.anuke.mindustry.entities.type.Player; import io.anuke.mindustry.game.*; import io.anuke.mindustry.type.*; import io.anuke.mindustry.world.Block; @@ -43,6 +39,7 @@ public class ContentLoader{ new Loadouts(), new TechTree(), new Zones(), + new TypeIDs(), //these are not really content classes, but this makes initialization easier new LegacyColorMapper(), @@ -59,8 +56,6 @@ public class ContentLoader{ return; } - registerTypes(); - for(ContentType type : ContentType.values()){ contentMap[type.ordinal()] = new Array<>(); contentNameMap[type.ordinal()] = new ObjectMap<>(); @@ -232,14 +227,4 @@ public class ContentLoader{ public Array units(){ return getBy(ContentType.unit); } - - /** - * Registers sync IDs for all types of sync entities. - * Do not register units here! - */ - private void registerTypes(){ - TypeTrait.registerType(Player.class, Player::new); - TypeTrait.registerType(Fire.class, Fire::new); - TypeTrait.registerType(Puddle.class, Puddle::new); - } } diff --git a/core/src/io/anuke/mindustry/core/Control.java b/core/src/io/anuke/mindustry/core/Control.java index 03c484a075..43f197ad3e 100644 --- a/core/src/io/anuke/mindustry/core/Control.java +++ b/core/src/io/anuke/mindustry/core/Control.java @@ -11,7 +11,6 @@ import io.anuke.arc.scene.ui.TextField; import io.anuke.arc.util.*; import io.anuke.mindustry.core.GameState.State; import io.anuke.mindustry.entities.Effects; -import io.anuke.mindustry.entities.traits.TypeTrait; import io.anuke.mindustry.entities.type.Player; import io.anuke.mindustry.game.*; import io.anuke.mindustry.game.EventType.*; @@ -271,10 +270,6 @@ public class Control implements ApplicationListener{ dialog.show(); }); } - - for(int i = 0; i < TypeTrait.registeredTypes.size; i++){ - Log.info("{0} = {1}", i, TypeTrait.getTypeByID(i).get().getClass().getSimpleName()); - } } @Override diff --git a/core/src/io/anuke/mindustry/core/NetClient.java b/core/src/io/anuke/mindustry/core/NetClient.java index 05ea541609..f873e5d1f5 100644 --- a/core/src/io/anuke/mindustry/core/NetClient.java +++ b/core/src/io/anuke/mindustry/core/NetClient.java @@ -15,9 +15,9 @@ import io.anuke.mindustry.entities.Entities; import io.anuke.mindustry.entities.EntityGroup; import io.anuke.mindustry.entities.traits.BuilderTrait.BuildRequest; import io.anuke.mindustry.entities.traits.SyncTrait; -import io.anuke.mindustry.entities.traits.TypeTrait; import io.anuke.mindustry.entities.type.Player; import io.anuke.mindustry.entities.type.Unit; +import io.anuke.mindustry.game.TypeID; import io.anuke.mindustry.game.Version; import io.anuke.mindustry.gen.Call; import io.anuke.mindustry.gen.RemoteReadClient; @@ -25,6 +25,7 @@ import io.anuke.mindustry.net.Administration.TraceInfo; import io.anuke.mindustry.net.*; import io.anuke.mindustry.net.Net.SendMode; import io.anuke.mindustry.net.Packets.*; +import io.anuke.mindustry.type.ContentType; import io.anuke.mindustry.world.Tile; import io.anuke.mindustry.world.modules.ItemModule; @@ -240,7 +241,7 @@ public class NetClient implements ApplicationListener{ //entity must not be added yet, so create it if(entity == null){ - entity = (SyncTrait)TypeTrait.getTypeByID(typeID).get(); //create entity from supplier + entity = (SyncTrait)content.getByID(ContentType.typeid, typeID).constructor.get(); entity.resetID(id); if(!netClient.isEntityUsed(entity.getID())){ add = true; diff --git a/core/src/io/anuke/mindustry/core/NetServer.java b/core/src/io/anuke/mindustry/core/NetServer.java index e079ab7511..b9c8510b02 100644 --- a/core/src/io/anuke/mindustry/core/NetServer.java +++ b/core/src/io/anuke/mindustry/core/NetServer.java @@ -474,7 +474,7 @@ public class NetServer implements ApplicationListener{ //write all entities now dataStream.writeInt(entity.getID()); //write id - dataStream.writeByte(sync.getTypeID()); //write type ID + dataStream.writeByte(sync.getTypeID().id); //write type ID sync.write(dataStream); //write entity sent++; diff --git a/core/src/io/anuke/mindustry/entities/effect/Fire.java b/core/src/io/anuke/mindustry/entities/effect/Fire.java index 7a6d02dbef..19ceadf09c 100644 --- a/core/src/io/anuke/mindustry/entities/effect/Fire.java +++ b/core/src/io/anuke/mindustry/entities/effect/Fire.java @@ -5,13 +5,15 @@ import io.anuke.arc.collection.IntMap; import io.anuke.arc.math.Mathf; import io.anuke.arc.math.geom.Geometry; import io.anuke.arc.math.geom.Point2; -import io.anuke.arc.util.*; +import io.anuke.arc.util.Structs; +import io.anuke.arc.util.Time; import io.anuke.mindustry.content.*; import io.anuke.mindustry.entities.*; import io.anuke.mindustry.entities.impl.TimedEntity; import io.anuke.mindustry.entities.traits.SaveTrait; import io.anuke.mindustry.entities.traits.SyncTrait; import io.anuke.mindustry.entities.type.TileEntity; +import io.anuke.mindustry.game.TypeID; import io.anuke.mindustry.gen.Call; import io.anuke.mindustry.net.Net; import io.anuke.mindustry.world.*; @@ -75,6 +77,11 @@ public class Fire extends TimedEntity implements SaveTrait, SyncTrait{ } } + @Override + public TypeID getTypeID(){ + return TypeIDs.fire; + } + @Override public byte version(){ return 0; diff --git a/core/src/io/anuke/mindustry/entities/effect/Puddle.java b/core/src/io/anuke/mindustry/entities/effect/Puddle.java index 4b633ac41d..292e5d7dae 100644 --- a/core/src/io/anuke/mindustry/entities/effect/Puddle.java +++ b/core/src/io/anuke/mindustry/entities/effect/Puddle.java @@ -16,6 +16,7 @@ import io.anuke.mindustry.content.*; import io.anuke.mindustry.entities.*; import io.anuke.mindustry.entities.impl.SolidEntity; import io.anuke.mindustry.entities.traits.*; +import io.anuke.mindustry.game.TypeID; import io.anuke.mindustry.gen.Call; import io.anuke.mindustry.net.Net; import io.anuke.mindustry.type.Liquid; @@ -143,6 +144,11 @@ public class Puddle extends SolidEntity implements SaveTrait, Poolable, DrawTrai return liquid.flammability * amount; } + @Override + public TypeID getTypeID(){ + return TypeIDs.puddle; + } + @Override public byte version(){ return 0; diff --git a/core/src/io/anuke/mindustry/entities/traits/TypeTrait.java b/core/src/io/anuke/mindustry/entities/traits/TypeTrait.java index a9f953281f..9e53f9678a 100644 --- a/core/src/io/anuke/mindustry/entities/traits/TypeTrait.java +++ b/core/src/io/anuke/mindustry/entities/traits/TypeTrait.java @@ -1,6 +1,10 @@ package io.anuke.mindustry.entities.traits; +import io.anuke.mindustry.game.TypeID; + public interface TypeTrait{ + + TypeID getTypeID(); /* int[] lastRegisteredID = {0}; Array> registeredTypes = new Array<>(); diff --git a/core/src/io/anuke/mindustry/entities/type/BaseUnit.java b/core/src/io/anuke/mindustry/entities/type/BaseUnit.java index 88f9090f5e..53ff4ede51 100644 --- a/core/src/io/anuke/mindustry/entities/type/BaseUnit.java +++ b/core/src/io/anuke/mindustry/entities/type/BaseUnit.java @@ -19,6 +19,7 @@ import io.anuke.mindustry.entities.traits.ShooterTrait; import io.anuke.mindustry.entities.traits.TargetTrait; import io.anuke.mindustry.entities.units.*; import io.anuke.mindustry.game.Team; +import io.anuke.mindustry.game.TypeID; import io.anuke.mindustry.gen.Call; import io.anuke.mindustry.net.Net; import io.anuke.mindustry.type.*; @@ -80,6 +81,11 @@ public abstract class BaseUnit extends Unit implements ShooterTrait{ return type.drag; } + @Override + public TypeID getTypeID(){ + return type.typeID; + } + public Tile getSpawner(){ return world.tile(spawner); } diff --git a/core/src/io/anuke/mindustry/entities/type/Player.java b/core/src/io/anuke/mindustry/entities/type/Player.java index 8c7b4b9293..91db0f1122 100644 --- a/core/src/io/anuke/mindustry/entities/type/Player.java +++ b/core/src/io/anuke/mindustry/entities/type/Player.java @@ -12,11 +12,11 @@ import io.anuke.arc.math.geom.*; import io.anuke.arc.util.*; import io.anuke.arc.util.pooling.Pools; import io.anuke.mindustry.Vars; -import io.anuke.mindustry.content.Fx; -import io.anuke.mindustry.content.Mechs; +import io.anuke.mindustry.content.*; import io.anuke.mindustry.entities.*; import io.anuke.mindustry.entities.traits.*; import io.anuke.mindustry.game.Team; +import io.anuke.mindustry.game.TypeID; import io.anuke.mindustry.gen.Call; import io.anuke.mindustry.graphics.Pal; import io.anuke.mindustry.input.Binding; @@ -115,6 +115,11 @@ public class Player extends Unit implements BuilderMinerTrait, ShooterTrait{ heal(); } + @Override + public TypeID getTypeID(){ + return TypeIDs.player; + } + @Override public void move(float x, float y){ if(!mech.flying){ diff --git a/core/src/io/anuke/mindustry/game/TypeID.java b/core/src/io/anuke/mindustry/game/TypeID.java new file mode 100644 index 0000000000..c054f9d8e9 --- /dev/null +++ b/core/src/io/anuke/mindustry/game/TypeID.java @@ -0,0 +1,19 @@ +package io.anuke.mindustry.game; + +import io.anuke.arc.function.Supplier; +import io.anuke.mindustry.entities.traits.TypeTrait; +import io.anuke.mindustry.type.ContentType; + +public class TypeID extends MappableContent{ + public final Supplier constructor; + + public TypeID(String name, Supplier constructor){ + super(name); + this.constructor = constructor; + } + + @Override + public ContentType getContentType(){ + return ContentType.typeid; + } +} diff --git a/core/src/io/anuke/mindustry/io/SaveVersion.java b/core/src/io/anuke/mindustry/io/SaveVersion.java index f1a7036878..d48fe46820 100644 --- a/core/src/io/anuke/mindustry/io/SaveVersion.java +++ b/core/src/io/anuke/mindustry/io/SaveVersion.java @@ -5,7 +5,8 @@ import io.anuke.arc.util.Time; import io.anuke.arc.util.io.CounterInputStream; import io.anuke.mindustry.entities.Entities; import io.anuke.mindustry.entities.EntityGroup; -import io.anuke.mindustry.entities.traits.*; +import io.anuke.mindustry.entities.traits.Entity; +import io.anuke.mindustry.entities.traits.SaveTrait; import io.anuke.mindustry.game.*; import io.anuke.mindustry.gen.BrokenBlock; import io.anuke.mindustry.maps.Map; @@ -19,6 +20,9 @@ import static io.anuke.mindustry.Vars.*; public abstract class SaveVersion extends SaveFileReader{ public final int version; + //HACK stores the last read build of the save file, valid after read meta call + private int lastReadBuild; + public SaveVersion(int version){ this.version = version; } @@ -77,6 +81,7 @@ public abstract class SaveVersion extends SaveFileReader{ state.stats = JsonIO.read(Stats.class, map.get("stats", "{}")); state.rules = JsonIO.read(Rules.class, map.get("rules", "{}")); if(state.rules.spawns.isEmpty()) state.rules.spawns = defaultWaves.get(); + lastReadBuild = map.getInt("build", -1); Map worldmap = world.maps.byName(map.get("mapname", "\\\\\\")); world.setMap(worldmap == null ? new Map(StringMap.of( @@ -221,7 +226,7 @@ public abstract class SaveVersion extends SaveFileReader{ SaveTrait save = (SaveTrait)entity; //each entity is a separate chunk. writeChunk(stream, true, out -> { - out.writeByte(save.getTypeID()); + out.writeByte(save.getTypeID().id); out.writeByte(save.version()); save.writeSave(out); }); @@ -231,7 +236,9 @@ public abstract class SaveVersion extends SaveFileReader{ } public void readEntities(DataInput stream) throws IOException{ - /* Latest data: + /* + Latest data: + 0 = Player 1 = Fire 2 = Puddle @@ -246,7 +253,45 @@ public abstract class SaveVersion extends SaveFileReader{ 11 = Wraith 12 = Ghoul 13 = Revenant + + Before removal of lightining/bullet: + + 0 = Player + 1 = Fire + 2 = Puddle + 3 = Bullet + 4 = Lightning + 5 = Draug + 6 = Spirit + 7 = Phantom + 8 = Dagger + 9 = Crawler + 10 = Titan + 11 = Fortress + 12 = Eruptor + 13 = Wraith + 14 = Ghoul + 15 = Revenant + + Before addition of new units: + + 0 = Player + 1 = Fire + 2 = Puddle + 3 = Bullet + 4 = Lightning + 5 = Spirit + 6 = Dagger + 7 = Crawler + 8 = Titan + 9 = Fortress + 10 = Eruptor + 11 = Wraith + 12 = Ghoul + 13 = Phantom + 14 = Revenant */ + byte groups = stream.readByte(); for(int i = 0; i < groups; i++){ @@ -256,7 +301,7 @@ public abstract class SaveVersion extends SaveFileReader{ readChunk(stream, true, in -> { byte typeid = in.readByte(); byte version = in.readByte(); - SaveTrait trait = (SaveTrait)TypeTrait.getTypeByID(typeid).get(); + SaveTrait trait = (SaveTrait)content.getByID(ContentType.typeid, typeid).constructor.get(); trait.readSave(in, version); }); } diff --git a/core/src/io/anuke/mindustry/io/versions/LegacyTypeTable.java b/core/src/io/anuke/mindustry/io/versions/LegacyTypeTable.java new file mode 100644 index 0000000000..52fc77f0c7 --- /dev/null +++ b/core/src/io/anuke/mindustry/io/versions/LegacyTypeTable.java @@ -0,0 +1,118 @@ +package io.anuke.mindustry.io.versions; + +import io.anuke.arc.function.Supplier; +import io.anuke.mindustry.entities.bullet.Bullet; +import io.anuke.mindustry.entities.effect.*; +import io.anuke.mindustry.entities.type.Player; +import io.anuke.mindustry.entities.type.base.*; + +/* +Latest data: [build 81] + +0 = Player +1 = Fire +2 = Puddle +3 = Draug +4 = Spirit +5 = Phantom +6 = Dagger +7 = Crawler +8 = Titan +9 = Fortress +10 = Eruptor +11 = Wraith +12 = Ghoul +13 = Revenant + +Before removal of lightining/bullet: [build 80] + +0 = Player +1 = Fire +2 = Puddle +3 = Bullet +4 = Lightning +5 = Draug +6 = Spirit +7 = Phantom +8 = Dagger +9 = Crawler +10 = Titan +11 = Fortress +12 = Eruptor +13 = Wraith +14 = Ghoul +15 = Revenant + +Before addition of new units: [build 79 and below] + +0 = Player +1 = Fire +2 = Puddle +3 = Bullet +4 = Lightning +5 = Spirit +6 = Dagger +7 = Crawler +8 = Titan +9 = Fortress +10 = Eruptor +11 = Wraith +12 = Ghoul +13 = Phantom +14 = Revenant + */ +public class LegacyTypeTable{ + private static final Supplier[] build81Table = { + Player::new, + Fire::new, + Puddle::new, + Draug::new, + Spirit::new, + Phantom::new, + Dagger::new, + Crawler::new, + Titan::new, + Fortress::new, + Eruptor::new, + Wraith::new, + Ghoul::new, + Revenant::new + }; + + private static final Supplier[] build80Table = { + Player::new, + Fire::new, + Puddle::new, + Bullet::new, //TODO reading these will crash + Lightning::new, + Draug::new, + Spirit::new, + Phantom::new, + Dagger::new, + Crawler::new, + Titan::new, + Fortress::new, + Eruptor::new, + Wraith::new, + Ghoul::new, + Revenant::new + }; + + private static final Supplier[] build79Table = { + Player::new, + Fire::new, + Puddle::new, + Bullet::new, //TODO reading these will crash + Lightning::new, + Spirit::new, + Dagger::new, + Crawler::new, + Titan::new, + Fortress::new, + Eruptor::new, + Wraith::new, + Ghoul::new, + Phantom::new, + Revenant::new + }; +} diff --git a/core/src/io/anuke/mindustry/type/ContentType.java b/core/src/io/anuke/mindustry/type/ContentType.java index 125ccc8221..31ddcf35d2 100644 --- a/core/src/io/anuke/mindustry/type/ContentType.java +++ b/core/src/io/anuke/mindustry/type/ContentType.java @@ -12,5 +12,6 @@ public enum ContentType{ weather, effect, zone, - loadout + loadout, + typeid } diff --git a/core/src/io/anuke/mindustry/type/UnitType.java b/core/src/io/anuke/mindustry/type/UnitType.java index 1500fb2738..485ee7d818 100644 --- a/core/src/io/anuke/mindustry/type/UnitType.java +++ b/core/src/io/anuke/mindustry/type/UnitType.java @@ -6,14 +6,14 @@ import io.anuke.arc.function.Supplier; import io.anuke.arc.graphics.g2d.TextureRegion; import io.anuke.arc.scene.ui.layout.Table; import io.anuke.mindustry.content.Items; -import io.anuke.mindustry.entities.traits.TypeTrait; import io.anuke.mindustry.entities.type.BaseUnit; -import io.anuke.mindustry.game.Team; -import io.anuke.mindustry.game.UnlockableContent; +import io.anuke.mindustry.game.*; import io.anuke.mindustry.ui.ContentDisplay; public class UnitType extends UnlockableContent{ - protected final Supplier constructor; + public final TypeID typeID; + public final Supplier constructor; + public float health = 60; public float hitsize = 7f; public float hitsizeTile = 4f; @@ -42,8 +42,7 @@ public class UnitType extends UnlockableContent{ super(name); this.constructor = mainConstructor; this.description = Core.bundle.getOrNull("unit." + name + ".description"); - - TypeTrait.registerType(type, mainConstructor); + this.typeID = new TypeID(name, mainConstructor); } @Override