Work on fixing entity ID mapping

This commit is contained in:
Anuken
2019-07-03 09:50:33 -04:00
parent 4e873f8bf3
commit 78215363dc
15 changed files with 247 additions and 38 deletions
@@ -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);
}
}
@@ -7,10 +7,6 @@ import io.anuke.arc.graphics.Pixmap;
import io.anuke.arc.util.Log; import io.anuke.arc.util.Log;
import io.anuke.mindustry.content.*; import io.anuke.mindustry.content.*;
import io.anuke.mindustry.entities.bullet.BulletType; 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.game.*;
import io.anuke.mindustry.type.*; import io.anuke.mindustry.type.*;
import io.anuke.mindustry.world.Block; import io.anuke.mindustry.world.Block;
@@ -43,6 +39,7 @@ public class ContentLoader{
new Loadouts(), new Loadouts(),
new TechTree(), new TechTree(),
new Zones(), new Zones(),
new TypeIDs(),
//these are not really content classes, but this makes initialization easier //these are not really content classes, but this makes initialization easier
new LegacyColorMapper(), new LegacyColorMapper(),
@@ -59,8 +56,6 @@ public class ContentLoader{
return; return;
} }
registerTypes();
for(ContentType type : ContentType.values()){ for(ContentType type : ContentType.values()){
contentMap[type.ordinal()] = new Array<>(); contentMap[type.ordinal()] = new Array<>();
contentNameMap[type.ordinal()] = new ObjectMap<>(); contentNameMap[type.ordinal()] = new ObjectMap<>();
@@ -232,14 +227,4 @@ public class ContentLoader{
public Array<UnitType> units(){ public Array<UnitType> units(){
return getBy(ContentType.unit); 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);
}
} }
@@ -11,7 +11,6 @@ import io.anuke.arc.scene.ui.TextField;
import io.anuke.arc.util.*; import io.anuke.arc.util.*;
import io.anuke.mindustry.core.GameState.State; import io.anuke.mindustry.core.GameState.State;
import io.anuke.mindustry.entities.Effects; import io.anuke.mindustry.entities.Effects;
import io.anuke.mindustry.entities.traits.TypeTrait;
import io.anuke.mindustry.entities.type.Player; import io.anuke.mindustry.entities.type.Player;
import io.anuke.mindustry.game.*; import io.anuke.mindustry.game.*;
import io.anuke.mindustry.game.EventType.*; import io.anuke.mindustry.game.EventType.*;
@@ -271,10 +270,6 @@ public class Control implements ApplicationListener{
dialog.show(); dialog.show();
}); });
} }
for(int i = 0; i < TypeTrait.registeredTypes.size; i++){
Log.info("{0} = {1}", i, TypeTrait.getTypeByID(i).get().getClass().getSimpleName());
}
} }
@Override @Override
@@ -15,9 +15,9 @@ import io.anuke.mindustry.entities.Entities;
import io.anuke.mindustry.entities.EntityGroup; import io.anuke.mindustry.entities.EntityGroup;
import io.anuke.mindustry.entities.traits.BuilderTrait.BuildRequest; import io.anuke.mindustry.entities.traits.BuilderTrait.BuildRequest;
import io.anuke.mindustry.entities.traits.SyncTrait; 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.Player;
import io.anuke.mindustry.entities.type.Unit; import io.anuke.mindustry.entities.type.Unit;
import io.anuke.mindustry.game.TypeID;
import io.anuke.mindustry.game.Version; import io.anuke.mindustry.game.Version;
import io.anuke.mindustry.gen.Call; import io.anuke.mindustry.gen.Call;
import io.anuke.mindustry.gen.RemoteReadClient; 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.*;
import io.anuke.mindustry.net.Net.SendMode; import io.anuke.mindustry.net.Net.SendMode;
import io.anuke.mindustry.net.Packets.*; import io.anuke.mindustry.net.Packets.*;
import io.anuke.mindustry.type.ContentType;
import io.anuke.mindustry.world.Tile; import io.anuke.mindustry.world.Tile;
import io.anuke.mindustry.world.modules.ItemModule; 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 //entity must not be added yet, so create it
if(entity == null){ if(entity == null){
entity = (SyncTrait)TypeTrait.getTypeByID(typeID).get(); //create entity from supplier entity = (SyncTrait)content.<TypeID>getByID(ContentType.typeid, typeID).constructor.get();
entity.resetID(id); entity.resetID(id);
if(!netClient.isEntityUsed(entity.getID())){ if(!netClient.isEntityUsed(entity.getID())){
add = true; add = true;
@@ -474,7 +474,7 @@ public class NetServer implements ApplicationListener{
//write all entities now //write all entities now
dataStream.writeInt(entity.getID()); //write id 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 sync.write(dataStream); //write entity
sent++; sent++;
@@ -5,13 +5,15 @@ import io.anuke.arc.collection.IntMap;
import io.anuke.arc.math.Mathf; import io.anuke.arc.math.Mathf;
import io.anuke.arc.math.geom.Geometry; import io.anuke.arc.math.geom.Geometry;
import io.anuke.arc.math.geom.Point2; 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.content.*;
import io.anuke.mindustry.entities.*; import io.anuke.mindustry.entities.*;
import io.anuke.mindustry.entities.impl.TimedEntity; import io.anuke.mindustry.entities.impl.TimedEntity;
import io.anuke.mindustry.entities.traits.SaveTrait; import io.anuke.mindustry.entities.traits.SaveTrait;
import io.anuke.mindustry.entities.traits.SyncTrait; import io.anuke.mindustry.entities.traits.SyncTrait;
import io.anuke.mindustry.entities.type.TileEntity; import io.anuke.mindustry.entities.type.TileEntity;
import io.anuke.mindustry.game.TypeID;
import io.anuke.mindustry.gen.Call; import io.anuke.mindustry.gen.Call;
import io.anuke.mindustry.net.Net; import io.anuke.mindustry.net.Net;
import io.anuke.mindustry.world.*; 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 @Override
public byte version(){ public byte version(){
return 0; return 0;
@@ -16,6 +16,7 @@ import io.anuke.mindustry.content.*;
import io.anuke.mindustry.entities.*; import io.anuke.mindustry.entities.*;
import io.anuke.mindustry.entities.impl.SolidEntity; import io.anuke.mindustry.entities.impl.SolidEntity;
import io.anuke.mindustry.entities.traits.*; import io.anuke.mindustry.entities.traits.*;
import io.anuke.mindustry.game.TypeID;
import io.anuke.mindustry.gen.Call; import io.anuke.mindustry.gen.Call;
import io.anuke.mindustry.net.Net; import io.anuke.mindustry.net.Net;
import io.anuke.mindustry.type.Liquid; import io.anuke.mindustry.type.Liquid;
@@ -143,6 +144,11 @@ public class Puddle extends SolidEntity implements SaveTrait, Poolable, DrawTrai
return liquid.flammability * amount; return liquid.flammability * amount;
} }
@Override
public TypeID getTypeID(){
return TypeIDs.puddle;
}
@Override @Override
public byte version(){ public byte version(){
return 0; return 0;
@@ -1,6 +1,10 @@
package io.anuke.mindustry.entities.traits; package io.anuke.mindustry.entities.traits;
import io.anuke.mindustry.game.TypeID;
public interface TypeTrait{ public interface TypeTrait{
TypeID getTypeID();
/* /*
int[] lastRegisteredID = {0}; int[] lastRegisteredID = {0};
Array<Supplier<? extends TypeTrait>> registeredTypes = new Array<>(); Array<Supplier<? extends TypeTrait>> registeredTypes = new Array<>();
@@ -19,6 +19,7 @@ import io.anuke.mindustry.entities.traits.ShooterTrait;
import io.anuke.mindustry.entities.traits.TargetTrait; import io.anuke.mindustry.entities.traits.TargetTrait;
import io.anuke.mindustry.entities.units.*; import io.anuke.mindustry.entities.units.*;
import io.anuke.mindustry.game.Team; import io.anuke.mindustry.game.Team;
import io.anuke.mindustry.game.TypeID;
import io.anuke.mindustry.gen.Call; import io.anuke.mindustry.gen.Call;
import io.anuke.mindustry.net.Net; import io.anuke.mindustry.net.Net;
import io.anuke.mindustry.type.*; import io.anuke.mindustry.type.*;
@@ -80,6 +81,11 @@ public abstract class BaseUnit extends Unit implements ShooterTrait{
return type.drag; return type.drag;
} }
@Override
public TypeID getTypeID(){
return type.typeID;
}
public Tile getSpawner(){ public Tile getSpawner(){
return world.tile(spawner); return world.tile(spawner);
} }
@@ -12,11 +12,11 @@ import io.anuke.arc.math.geom.*;
import io.anuke.arc.util.*; import io.anuke.arc.util.*;
import io.anuke.arc.util.pooling.Pools; import io.anuke.arc.util.pooling.Pools;
import io.anuke.mindustry.Vars; import io.anuke.mindustry.Vars;
import io.anuke.mindustry.content.Fx; import io.anuke.mindustry.content.*;
import io.anuke.mindustry.content.Mechs;
import io.anuke.mindustry.entities.*; import io.anuke.mindustry.entities.*;
import io.anuke.mindustry.entities.traits.*; import io.anuke.mindustry.entities.traits.*;
import io.anuke.mindustry.game.Team; import io.anuke.mindustry.game.Team;
import io.anuke.mindustry.game.TypeID;
import io.anuke.mindustry.gen.Call; import io.anuke.mindustry.gen.Call;
import io.anuke.mindustry.graphics.Pal; import io.anuke.mindustry.graphics.Pal;
import io.anuke.mindustry.input.Binding; import io.anuke.mindustry.input.Binding;
@@ -115,6 +115,11 @@ public class Player extends Unit implements BuilderMinerTrait, ShooterTrait{
heal(); heal();
} }
@Override
public TypeID getTypeID(){
return TypeIDs.player;
}
@Override @Override
public void move(float x, float y){ public void move(float x, float y){
if(!mech.flying){ if(!mech.flying){
@@ -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<? extends TypeTrait> constructor;
public TypeID(String name, Supplier<? extends TypeTrait> constructor){
super(name);
this.constructor = constructor;
}
@Override
public ContentType getContentType(){
return ContentType.typeid;
}
}
@@ -5,7 +5,8 @@ import io.anuke.arc.util.Time;
import io.anuke.arc.util.io.CounterInputStream; import io.anuke.arc.util.io.CounterInputStream;
import io.anuke.mindustry.entities.Entities; import io.anuke.mindustry.entities.Entities;
import io.anuke.mindustry.entities.EntityGroup; 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.game.*;
import io.anuke.mindustry.gen.BrokenBlock; import io.anuke.mindustry.gen.BrokenBlock;
import io.anuke.mindustry.maps.Map; import io.anuke.mindustry.maps.Map;
@@ -19,6 +20,9 @@ import static io.anuke.mindustry.Vars.*;
public abstract class SaveVersion extends SaveFileReader{ public abstract class SaveVersion extends SaveFileReader{
public final int version; 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){ public SaveVersion(int version){
this.version = version; this.version = version;
} }
@@ -77,6 +81,7 @@ public abstract class SaveVersion extends SaveFileReader{
state.stats = JsonIO.read(Stats.class, map.get("stats", "{}")); state.stats = JsonIO.read(Stats.class, map.get("stats", "{}"));
state.rules = JsonIO.read(Rules.class, map.get("rules", "{}")); state.rules = JsonIO.read(Rules.class, map.get("rules", "{}"));
if(state.rules.spawns.isEmpty()) state.rules.spawns = defaultWaves.get(); if(state.rules.spawns.isEmpty()) state.rules.spawns = defaultWaves.get();
lastReadBuild = map.getInt("build", -1);
Map worldmap = world.maps.byName(map.get("mapname", "\\\\\\")); Map worldmap = world.maps.byName(map.get("mapname", "\\\\\\"));
world.setMap(worldmap == null ? new Map(StringMap.of( world.setMap(worldmap == null ? new Map(StringMap.of(
@@ -221,7 +226,7 @@ public abstract class SaveVersion extends SaveFileReader{
SaveTrait save = (SaveTrait)entity; SaveTrait save = (SaveTrait)entity;
//each entity is a separate chunk. //each entity is a separate chunk.
writeChunk(stream, true, out -> { writeChunk(stream, true, out -> {
out.writeByte(save.getTypeID()); out.writeByte(save.getTypeID().id);
out.writeByte(save.version()); out.writeByte(save.version());
save.writeSave(out); save.writeSave(out);
}); });
@@ -231,7 +236,9 @@ public abstract class SaveVersion extends SaveFileReader{
} }
public void readEntities(DataInput stream) throws IOException{ public void readEntities(DataInput stream) throws IOException{
/* Latest data: /*
Latest data:
0 = Player 0 = Player
1 = Fire 1 = Fire
2 = Puddle 2 = Puddle
@@ -246,7 +253,45 @@ public abstract class SaveVersion extends SaveFileReader{
11 = Wraith 11 = Wraith
12 = Ghoul 12 = Ghoul
13 = Revenant 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(); byte groups = stream.readByte();
for(int i = 0; i < groups; i++){ for(int i = 0; i < groups; i++){
@@ -256,7 +301,7 @@ public abstract class SaveVersion extends SaveFileReader{
readChunk(stream, true, in -> { readChunk(stream, true, in -> {
byte typeid = in.readByte(); byte typeid = in.readByte();
byte version = in.readByte(); byte version = in.readByte();
SaveTrait trait = (SaveTrait)TypeTrait.getTypeByID(typeid).get(); SaveTrait trait = (SaveTrait)content.<TypeID>getByID(ContentType.typeid, typeid).constructor.get();
trait.readSave(in, version); trait.readSave(in, version);
}); });
} }
@@ -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
};
}
@@ -12,5 +12,6 @@ public enum ContentType{
weather, weather,
effect, effect,
zone, zone,
loadout loadout,
typeid
} }
@@ -6,14 +6,14 @@ import io.anuke.arc.function.Supplier;
import io.anuke.arc.graphics.g2d.TextureRegion; import io.anuke.arc.graphics.g2d.TextureRegion;
import io.anuke.arc.scene.ui.layout.Table; import io.anuke.arc.scene.ui.layout.Table;
import io.anuke.mindustry.content.Items; import io.anuke.mindustry.content.Items;
import io.anuke.mindustry.entities.traits.TypeTrait;
import io.anuke.mindustry.entities.type.BaseUnit; import io.anuke.mindustry.entities.type.BaseUnit;
import io.anuke.mindustry.game.Team; import io.anuke.mindustry.game.*;
import io.anuke.mindustry.game.UnlockableContent;
import io.anuke.mindustry.ui.ContentDisplay; import io.anuke.mindustry.ui.ContentDisplay;
public class UnitType extends UnlockableContent{ public class UnitType extends UnlockableContent{
protected final Supplier<? extends BaseUnit> constructor; public final TypeID typeID;
public final Supplier<? extends BaseUnit> constructor;
public float health = 60; public float health = 60;
public float hitsize = 7f; public float hitsize = 7f;
public float hitsizeTile = 4f; public float hitsizeTile = 4f;
@@ -42,8 +42,7 @@ public class UnitType extends UnlockableContent{
super(name); super(name);
this.constructor = mainConstructor; this.constructor = mainConstructor;
this.description = Core.bundle.getOrNull("unit." + name + ".description"); this.description = Core.bundle.getOrNull("unit." + name + ".description");
this.typeID = new TypeID(name, mainConstructor);
TypeTrait.registerType(type, mainConstructor);
} }
@Override @Override