mirror of
https://github.com/Anuken/Mindustry.git
synced 2026-01-26 06:22:17 -08:00
Autogenerated interpolation
This commit is contained in:
parent
1acb5fc56c
commit
7c06ba94c1
36 changed files with 252 additions and 183 deletions
|
|
@ -17,7 +17,15 @@ public class Annotations{
|
|||
public @interface Final{
|
||||
}
|
||||
|
||||
/** Indicates that a component field is imported from other components. */
|
||||
/** Indicates that a field will be interpolated when synced. */
|
||||
@Target({ElementType.FIELD})
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
public @interface SyncField{
|
||||
/** If true, the field will be linearly interpolated. If false, it will be interpolated as an angle. */
|
||||
boolean value();
|
||||
}
|
||||
|
||||
/** Indicates that a component field is imported from other components. This means it doesn't actually exist. */
|
||||
@Target({ElementType.FIELD})
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
public @interface Import{
|
||||
|
|
|
|||
|
|
@ -1,12 +1,14 @@
|
|||
package mindustry.annotations.entity;
|
||||
|
||||
import arc.files.*;
|
||||
import arc.math.*;
|
||||
import arc.struct.*;
|
||||
import arc.util.*;
|
||||
import arc.util.serialization.*;
|
||||
import com.squareup.javapoet.*;
|
||||
import mindustry.annotations.Annotations.*;
|
||||
import mindustry.annotations.*;
|
||||
import mindustry.annotations.util.*;
|
||||
import mindustry.annotations.util.TypeIOResolver.*;
|
||||
|
||||
import javax.lang.model.element.*;
|
||||
|
|
@ -15,6 +17,8 @@ import static mindustry.annotations.BaseProcessor.instanceOf;
|
|||
|
||||
public class EntityIO{
|
||||
final static Json json = new Json();
|
||||
//suffixes for sync fields
|
||||
final static String targetSuf = "_TARGET_", lastSuf = "_LAST_";
|
||||
|
||||
final ClassSerializer serializer;
|
||||
final String name;
|
||||
|
|
@ -104,6 +108,83 @@ public class EntityIO{
|
|||
}
|
||||
}
|
||||
|
||||
void writeSync(MethodSpec.Builder method, boolean write, Array<Svar> syncFields) throws Exception{
|
||||
this.method = method;
|
||||
this.write = write;
|
||||
|
||||
if(write){
|
||||
//write uses most recent revision
|
||||
for(RevisionField field : revisions.peek().fields){
|
||||
io(field.type, "this." + field.name);
|
||||
}
|
||||
}else{
|
||||
Revision rev = revisions.peek();
|
||||
|
||||
//base read code
|
||||
st("if(lastUpdated != 0) updateSpacing = $T.timeSinceMillis(lastUpdated)", Time.class);
|
||||
st("lastUpdated = $T.millis()", Time.class);
|
||||
|
||||
//add code for reading revision
|
||||
for(RevisionField field : rev.fields){
|
||||
Svar sf = syncFields.find(s -> s.name().equals(field.name));
|
||||
if(sf != null){
|
||||
st(field.name + lastSuf + " = this." + field.name);
|
||||
}
|
||||
|
||||
io(field.type, "this." + (sf != null ? field.name + targetSuf : field.name) + " = ");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void writeSyncManual(MethodSpec.Builder method, boolean write, Array<Svar> syncFields) throws Exception{
|
||||
this.method = method;
|
||||
this.write = write;
|
||||
|
||||
if(write){
|
||||
for(Svar field : syncFields){
|
||||
st("buffer.put(this.$L)", field.name());
|
||||
}
|
||||
}else{
|
||||
//base read code
|
||||
st("if(lastUpdated != 0) updateSpacing = $T.timeSinceMillis(lastUpdated)", Time.class);
|
||||
st("lastUpdated = $T.millis()", Time.class);
|
||||
|
||||
//just read the field
|
||||
for(Svar field : syncFields){
|
||||
//last
|
||||
st("this.$L = this.$L", field.name() + lastSuf, field.name());
|
||||
//assign target
|
||||
st("this.$L = buffer.get()", field.name() + targetSuf);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void writeInterpolate(MethodSpec.Builder method, Array<Svar> fields) throws Exception{
|
||||
this.method = method;
|
||||
|
||||
cont("if(lastUpdated != 0 && updateSpacing != 0)");
|
||||
|
||||
//base calculations
|
||||
st("float timeSinceUpdate = Time.timeSinceMillis(lastUpdated)");
|
||||
st("float alpha = Math.min(timeSinceUpdate / updateSpacing, 2f)");
|
||||
|
||||
//write interpolated data, using slerp / lerp
|
||||
for(Svar field : fields){
|
||||
String name = field.name(), targetName = name + targetSuf, lastName = name + lastSuf;
|
||||
st("$L = $T.$L($L, $L, alpha)", name, Mathf.class, field.annotation(SyncField.class).value() ? "lerp" : "slerp", lastName, targetName);
|
||||
}
|
||||
|
||||
ncont("else"); //no meaningful data has arrived yet
|
||||
|
||||
//write values directly to targets
|
||||
for(Svar field : fields){
|
||||
String name = field.name(), targetName = name + targetSuf;
|
||||
st("$L = $L", name, targetName);
|
||||
}
|
||||
|
||||
econt();
|
||||
}
|
||||
|
||||
private void io(String type, String field) throws Exception{
|
||||
if(BaseProcessor.isPrimitive(type)){
|
||||
s(type.equals("boolean") ? "bool" : type.charAt(0) + "", field);
|
||||
|
|
|
|||
|
|
@ -218,10 +218,13 @@ public class EntityProcess extends BaseProcessor{
|
|||
//add serialize() boolean
|
||||
builder.addMethod(MethodSpec.methodBuilder("serialize").addModifiers(Modifier.PUBLIC, Modifier.FINAL).returns(boolean.class).addStatement("return " + ann.serialize()).build());
|
||||
|
||||
//all SyncField fields
|
||||
Array<Svar> syncedFields = new Array<>();
|
||||
|
||||
//add all components
|
||||
for(Stype comp : components){
|
||||
|
||||
//write fields to the class; ignoring transient ones
|
||||
//write fields to the class; ignoring transient/imported ones
|
||||
Array<Svar> fields = comp.fields().select(f -> !f.has(Import.class));
|
||||
for(Svar f : fields){
|
||||
if(!usedFields.add(f.name())){
|
||||
|
|
@ -239,6 +242,7 @@ public class EntityProcess extends BaseProcessor{
|
|||
if(f.is(Modifier.TRANSIENT)){
|
||||
fbuilder.addModifiers(Modifier.TRANSIENT);
|
||||
}
|
||||
|
||||
//add initializer if it exists
|
||||
if(varInitializers.containsKey(f)){
|
||||
fbuilder.initializer(varInitializers.get(f));
|
||||
|
|
@ -248,6 +252,24 @@ public class EntityProcess extends BaseProcessor{
|
|||
fbuilder.addAnnotations(f.annotations().map(AnnotationSpec::get));
|
||||
builder.addField(fbuilder.build());
|
||||
specVariables.put(builder.fieldSpecs.get(builder.fieldSpecs.size() - 1), f);
|
||||
|
||||
//add extra sync fields
|
||||
if(f.has(SyncField.class)){
|
||||
if(!f.tname().toString().equals("float")) err("All SyncFields must be of type float", f);
|
||||
|
||||
syncedFields.add(f);
|
||||
|
||||
//a synced field has 3 values:
|
||||
//- target state
|
||||
//- last state
|
||||
//- current state (the field itself, will be written to)
|
||||
|
||||
//target
|
||||
builder.addField(FieldSpec.builder(float.class, f.name() + EntityIO.targetSuf).addModifiers(Modifier.TRANSIENT, Modifier.PRIVATE).build());
|
||||
|
||||
//last
|
||||
builder.addField(FieldSpec.builder(float.class, f.name() + EntityIO.lastSuf).addModifiers(Modifier.TRANSIENT, Modifier.PRIVATE).build());
|
||||
}
|
||||
}
|
||||
|
||||
//get all utility methods from components
|
||||
|
|
@ -256,6 +278,8 @@ public class EntityProcess extends BaseProcessor{
|
|||
}
|
||||
}
|
||||
|
||||
syncedFields.sortComparing(Selement::name);
|
||||
|
||||
//override toString method
|
||||
builder.addMethod(MethodSpec.methodBuilder("toString")
|
||||
.addAnnotation(Override.class)
|
||||
|
|
@ -264,6 +288,7 @@ public class EntityProcess extends BaseProcessor{
|
|||
.addStatement("return $S + $L", name + "#", "id").build());
|
||||
|
||||
EntityIO io = ann.serialize() ? new EntityIO(type.name(), builder, serializer, rootDirectory.child("annotations/src/main/resources/revisions").child(name)) : null;
|
||||
boolean hasIO = ann.genio() && ann.serialize();
|
||||
|
||||
//add all methods from components
|
||||
for(ObjectMap.Entry<String, Array<Smethod>> entry : methods){
|
||||
|
|
@ -322,10 +347,38 @@ public class EntityProcess extends BaseProcessor{
|
|||
}
|
||||
}
|
||||
|
||||
//SPECIAL CASE: I/O code
|
||||
//note that serialization is generated even for non-serializing entities for manual usage
|
||||
if((first.name().equals("read") || first.name().equals("write")) && ann.genio() && ann.serialize()){
|
||||
io.write(mbuilder, first.name().equals("write"));
|
||||
if(io != null){
|
||||
//SPECIAL CASE: I/O code
|
||||
//note that serialization is generated even for non-serializing entities for manual usage
|
||||
if((first.name().equals("read") || first.name().equals("write")) && hasIO){
|
||||
io.write(mbuilder, first.name().equals("write"));
|
||||
}
|
||||
|
||||
//SPECIAL CASE: sync I/O code
|
||||
if((first.name().equals("readSync") || first.name().equals("writeSync")) && hasIO){
|
||||
io.writeSync(mbuilder, first.name().equals("writeSync"), syncedFields);
|
||||
}
|
||||
|
||||
//SPECIAL CASE: sync I/O code for writing to/from a manual buffer
|
||||
if((first.name().equals("readSyncManual") || first.name().equals("writeSyncManual")) && hasIO){
|
||||
io.writeSyncManual(mbuilder, first.name().equals("writeSyncManual"), syncedFields);
|
||||
}
|
||||
|
||||
//SPECIAL CASE: interpolate method implementation
|
||||
if(first.name().equals("interpolate")){
|
||||
io.writeInterpolate(mbuilder, syncedFields);
|
||||
}
|
||||
|
||||
//snap to target position
|
||||
if(first.name().equals("snapSync")){
|
||||
mbuilder.addStatement("updateSpacing = 16");
|
||||
mbuilder.addStatement("lastUpdated = $T.millis()", Time.class);
|
||||
for(Svar field : syncedFields){
|
||||
//reset last+current state to target position
|
||||
mbuilder.addStatement("$L = $L", field.name() + EntityIO.lastSuf, field.name() + EntityIO.targetSuf);
|
||||
mbuilder.addStatement("$L = $L", field.name(), field.name() + EntityIO.targetSuf);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for(Smethod elem : entry.value){
|
||||
|
|
@ -373,12 +426,12 @@ public class EntityProcess extends BaseProcessor{
|
|||
//implement reset()
|
||||
MethodSpec.Builder resetBuilder = MethodSpec.methodBuilder("reset").addModifiers(Modifier.PUBLIC);
|
||||
for(FieldSpec spec : builder.fieldSpecs){
|
||||
Svar variable = specVariables.get(spec);
|
||||
if(variable.isAny(Modifier.STATIC, Modifier.FINAL)) continue;
|
||||
@Nullable Svar variable = specVariables.get(spec);
|
||||
if(variable != null && variable.isAny(Modifier.STATIC, Modifier.FINAL)) continue;
|
||||
|
||||
if(spec.type.isPrimitive()){
|
||||
//set to primitive default
|
||||
resetBuilder.addStatement("$L = $L", spec.name, varInitializers.containsKey(variable) ? varInitializers.get(variable) : getDefault(spec.type.toString()));
|
||||
resetBuilder.addStatement("$L = $L", spec.name, variable != null && varInitializers.containsKey(variable) ? varInitializers.get(variable) : getDefault(spec.type.toString()));
|
||||
}else{
|
||||
//set to default null
|
||||
if(!varInitializers.containsKey(variable)){
|
||||
|
|
|
|||
|
|
@ -1,19 +1,19 @@
|
|||
#Maps entity names to IDs. Autogenerated.
|
||||
|
||||
alpha=14
|
||||
dart=15
|
||||
draug=0
|
||||
mindustry.entities.comp.BulletComp=1
|
||||
mindustry.entities.comp.DecalComp=2
|
||||
mindustry.entities.comp.EffectComp=3
|
||||
mindustry.entities.comp.FireComp=4
|
||||
mindustry.entities.comp.PlayerComp=5
|
||||
mindustry.entities.comp.PuddleComp=6
|
||||
mindustry.entities.comp.TileComp=7
|
||||
mindustry.type.Weather.WeatherComp=8
|
||||
mindustry.world.blocks.storage.LaunchPad.LaunchPayloadComp=9
|
||||
oculon=16
|
||||
phantom=10
|
||||
titan=11
|
||||
vanguard=12
|
||||
wraith=13
|
||||
alpha=0
|
||||
block=1
|
||||
draug=2
|
||||
mindustry.entities.comp.BulletComp=3
|
||||
mindustry.entities.comp.DecalComp=4
|
||||
mindustry.entities.comp.EffectComp=5
|
||||
mindustry.entities.comp.FireComp=6
|
||||
mindustry.entities.comp.PlayerComp=7
|
||||
mindustry.entities.comp.PuddleComp=8
|
||||
mindustry.entities.comp.TileComp=9
|
||||
mindustry.type.Weather.WeatherComp=10
|
||||
mindustry.world.blocks.storage.LaunchPad.LaunchPayloadComp=11
|
||||
oculon=12
|
||||
phantom=13
|
||||
titan=14
|
||||
vanguard=15
|
||||
wraith=16
|
||||
|
|
@ -0,0 +1 @@
|
|||
{fields:[{name:armor,type:float,size:4},{name:elevation,type:float,size:4},{name:health,type:float,size:4},{name:rotation,type:float,size:4},{name:shield,type:float,size:4},{name:spawnedByCore,type:boolean,size:1},{name:stack,type:mindustry.type.ItemStack,size:-1},{name:statuses,type:arc.struct.Array<mindustry.entities.units.StatusEntry>,size:-1},{name:team,type:mindustry.game.Team,size:-1},{name:tile,type:Tilec,size:-1},{name:type,type:mindustry.type.UnitType,size:-1},{name:vel,type:arc.math.geom.Vec2,size:-1},{name:x,type:float,size:4},{name:y,type:float,size:4}]}
|
||||
|
|
@ -1 +1 @@
|
|||
{fields:[{name:elevation,type:float,size:4},{name:health,type:float,size:4},{name:requests,type:arc.struct.Queue<mindustry.entities.units.BuildRequest>,size:-1},{name:rotation,type:float,size:4},{name:shield,type:float,size:4},{name:stack,type:mindustry.type.ItemStack,size:-1},{name:statuses,type:arc.struct.Array<mindustry.entities.units.StatusEntry>,size:-1},{name:team,type:mindustry.game.Team,size:-1},{name:type,type:mindustry.type.UnitType,size:-1},{name:vel,type:arc.math.geom.Vec2,size:-1},{name:x,type:float,size:4},{name:y,type:float,size:4}]}
|
||||
{fields:[{name:armor,type:float,size:4},{name:elevation,type:float,size:4},{name:health,type:float,size:4},{name:requests,type:arc.struct.Queue<mindustry.entities.units.BuildRequest>,size:-1},{name:rotation,type:float,size:4},{name:shield,type:float,size:4},{name:spawnedByCore,type:boolean,size:1},{name:stack,type:mindustry.type.ItemStack,size:-1},{name:statuses,type:arc.struct.Array<mindustry.entities.units.StatusEntry>,size:-1},{name:team,type:mindustry.game.Team,size:-1},{name:type,type:mindustry.type.UnitType,size:-1},{name:vel,type:arc.math.geom.Vec2,size:-1},{name:x,type:float,size:4},{name:y,type:float,size:4}]}
|
||||
|
|
@ -1 +0,0 @@
|
|||
{version:1,fields:[{name:armor,type:float,size:4},{name:elevation,type:float,size:4},{name:health,type:float,size:4},{name:requests,type:arc.struct.Queue<mindustry.entities.units.BuildRequest>,size:-1},{name:rotation,type:float,size:4},{name:shield,type:float,size:4},{name:stack,type:mindustry.type.ItemStack,size:-1},{name:statuses,type:arc.struct.Array<mindustry.entities.units.StatusEntry>,size:-1},{name:team,type:mindustry.game.Team,size:-1},{name:type,type:mindustry.type.UnitType,size:-1},{name:vel,type:arc.math.geom.Vec2,size:-1},{name:x,type:float,size:4},{name:y,type:float,size:4}]}
|
||||
|
|
@ -1 +0,0 @@
|
|||
{version:2,fields:[{name:armor,type:float,size:4},{name:elevation,type:float,size:4},{name:health,type:float,size:4},{name:requests,type:arc.struct.Queue<mindustry.entities.units.BuildRequest>,size:-1},{name:rotation,type:float,size:4},{name:shield,type:float,size:4},{name:spawnedByCore,type:boolean,size:1},{name:stack,type:mindustry.type.ItemStack,size:-1},{name:statuses,type:arc.struct.Array<mindustry.entities.units.StatusEntry>,size:-1},{name:team,type:mindustry.game.Team,size:-1},{name:type,type:mindustry.type.UnitType,size:-1},{name:vel,type:arc.math.geom.Vec2,size:-1},{name:x,type:float,size:4},{name:y,type:float,size:4}]}
|
||||
|
|
@ -1 +1 @@
|
|||
{fields:[{name:elevation,type:float,size:4},{name:health,type:float,size:4},{name:rotation,type:float,size:4},{name:shield,type:float,size:4},{name:stack,type:mindustry.type.ItemStack,size:-1},{name:statuses,type:arc.struct.Array<mindustry.entities.units.StatusEntry>,size:-1},{name:team,type:mindustry.game.Team,size:-1},{name:type,type:mindustry.type.UnitType,size:-1},{name:vel,type:arc.math.geom.Vec2,size:-1},{name:x,type:float,size:4},{name:y,type:float,size:4}]}
|
||||
{fields:[{name:armor,type:float,size:4},{name:elevation,type:float,size:4},{name:health,type:float,size:4},{name:rotation,type:float,size:4},{name:shield,type:float,size:4},{name:spawnedByCore,type:boolean,size:1},{name:stack,type:mindustry.type.ItemStack,size:-1},{name:statuses,type:arc.struct.Array<mindustry.entities.units.StatusEntry>,size:-1},{name:team,type:mindustry.game.Team,size:-1},{name:type,type:mindustry.type.UnitType,size:-1},{name:vel,type:arc.math.geom.Vec2,size:-1},{name:x,type:float,size:4},{name:y,type:float,size:4}]}
|
||||
|
|
@ -1 +0,0 @@
|
|||
{version:1,fields:[{name:armor,type:float,size:4},{name:elevation,type:float,size:4},{name:health,type:float,size:4},{name:rotation,type:float,size:4},{name:shield,type:float,size:4},{name:stack,type:mindustry.type.ItemStack,size:-1},{name:statuses,type:arc.struct.Array<mindustry.entities.units.StatusEntry>,size:-1},{name:team,type:mindustry.game.Team,size:-1},{name:type,type:mindustry.type.UnitType,size:-1},{name:vel,type:arc.math.geom.Vec2,size:-1},{name:x,type:float,size:4},{name:y,type:float,size:4}]}
|
||||
|
|
@ -1 +0,0 @@
|
|||
{version:2,fields:[{name:armor,type:float,size:4},{name:elevation,type:float,size:4},{name:health,type:float,size:4},{name:rotation,type:float,size:4},{name:shield,type:float,size:4},{name:spawnedByCore,type:boolean,size:1},{name:stack,type:mindustry.type.ItemStack,size:-1},{name:statuses,type:arc.struct.Array<mindustry.entities.units.StatusEntry>,size:-1},{name:team,type:mindustry.game.Team,size:-1},{name:type,type:mindustry.type.UnitType,size:-1},{name:vel,type:arc.math.geom.Vec2,size:-1},{name:x,type:float,size:4},{name:y,type:float,size:4}]}
|
||||
|
|
@ -1 +1 @@
|
|||
{fields:[{name:baseRotation,type:float,size:4},{name:elevation,type:float,size:4},{name:health,type:float,size:4},{name:rotation,type:float,size:4},{name:shield,type:float,size:4},{name:stack,type:mindustry.type.ItemStack,size:-1},{name:statuses,type:arc.struct.Array<mindustry.entities.units.StatusEntry>,size:-1},{name:team,type:mindustry.game.Team,size:-1},{name:type,type:mindustry.type.UnitType,size:-1},{name:vel,type:arc.math.geom.Vec2,size:-1},{name:x,type:float,size:4},{name:y,type:float,size:4}]}
|
||||
{fields:[{name:armor,type:float,size:4},{name:baseRotation,type:float,size:4},{name:elevation,type:float,size:4},{name:health,type:float,size:4},{name:rotation,type:float,size:4},{name:shield,type:float,size:4},{name:spawnedByCore,type:boolean,size:1},{name:stack,type:mindustry.type.ItemStack,size:-1},{name:statuses,type:arc.struct.Array<mindustry.entities.units.StatusEntry>,size:-1},{name:team,type:mindustry.game.Team,size:-1},{name:type,type:mindustry.type.UnitType,size:-1},{name:vel,type:arc.math.geom.Vec2,size:-1},{name:x,type:float,size:4},{name:y,type:float,size:4}]}
|
||||
|
|
@ -1 +0,0 @@
|
|||
{version:1,fields:[{name:armor,type:float,size:4},{name:baseRotation,type:float,size:4},{name:elevation,type:float,size:4},{name:health,type:float,size:4},{name:rotation,type:float,size:4},{name:shield,type:float,size:4},{name:stack,type:mindustry.type.ItemStack,size:-1},{name:statuses,type:arc.struct.Array<mindustry.entities.units.StatusEntry>,size:-1},{name:team,type:mindustry.game.Team,size:-1},{name:type,type:mindustry.type.UnitType,size:-1},{name:vel,type:arc.math.geom.Vec2,size:-1},{name:x,type:float,size:4},{name:y,type:float,size:4}]}
|
||||
|
|
@ -1 +0,0 @@
|
|||
{version:2,fields:[{name:armor,type:float,size:4},{name:baseRotation,type:float,size:4},{name:elevation,type:float,size:4},{name:health,type:float,size:4},{name:rotation,type:float,size:4},{name:shield,type:float,size:4},{name:spawnedByCore,type:boolean,size:1},{name:stack,type:mindustry.type.ItemStack,size:-1},{name:statuses,type:arc.struct.Array<mindustry.entities.units.StatusEntry>,size:-1},{name:team,type:mindustry.game.Team,size:-1},{name:type,type:mindustry.type.UnitType,size:-1},{name:vel,type:arc.math.geom.Vec2,size:-1},{name:x,type:float,size:4},{name:y,type:float,size:4}]}
|
||||
|
|
@ -1 +1 @@
|
|||
{fields:[{name:elevation,type:float,size:4},{name:health,type:float,size:4},{name:mineTile,type:mindustry.world.Tile,size:-1},{name:rotation,type:float,size:4},{name:shield,type:float,size:4},{name:stack,type:mindustry.type.ItemStack,size:-1},{name:statuses,type:arc.struct.Array<mindustry.entities.units.StatusEntry>,size:-1},{name:team,type:mindustry.game.Team,size:-1},{name:type,type:mindustry.type.UnitType,size:-1},{name:vel,type:arc.math.geom.Vec2,size:-1},{name:x,type:float,size:4},{name:y,type:float,size:4}]}
|
||||
{fields:[{name:armor,type:float,size:4},{name:elevation,type:float,size:4},{name:health,type:float,size:4},{name:mineTile,type:mindustry.world.Tile,size:-1},{name:rotation,type:float,size:4},{name:shield,type:float,size:4},{name:spawnedByCore,type:boolean,size:1},{name:stack,type:mindustry.type.ItemStack,size:-1},{name:statuses,type:arc.struct.Array<mindustry.entities.units.StatusEntry>,size:-1},{name:team,type:mindustry.game.Team,size:-1},{name:type,type:mindustry.type.UnitType,size:-1},{name:vel,type:arc.math.geom.Vec2,size:-1},{name:x,type:float,size:4},{name:y,type:float,size:4}]}
|
||||
|
|
@ -1 +0,0 @@
|
|||
{version:1,fields:[{name:armor,type:float,size:4},{name:elevation,type:float,size:4},{name:health,type:float,size:4},{name:mineTile,type:mindustry.world.Tile,size:-1},{name:rotation,type:float,size:4},{name:shield,type:float,size:4},{name:stack,type:mindustry.type.ItemStack,size:-1},{name:statuses,type:arc.struct.Array<mindustry.entities.units.StatusEntry>,size:-1},{name:team,type:mindustry.game.Team,size:-1},{name:type,type:mindustry.type.UnitType,size:-1},{name:vel,type:arc.math.geom.Vec2,size:-1},{name:x,type:float,size:4},{name:y,type:float,size:4}]}
|
||||
|
|
@ -1 +0,0 @@
|
|||
{version:2,fields:[{name:armor,type:float,size:4},{name:elevation,type:float,size:4},{name:health,type:float,size:4},{name:mineTile,type:mindustry.world.Tile,size:-1},{name:rotation,type:float,size:4},{name:shield,type:float,size:4},{name:spawnedByCore,type:boolean,size:1},{name:stack,type:mindustry.type.ItemStack,size:-1},{name:statuses,type:arc.struct.Array<mindustry.entities.units.StatusEntry>,size:-1},{name:team,type:mindustry.game.Team,size:-1},{name:type,type:mindustry.type.UnitType,size:-1},{name:vel,type:arc.math.geom.Vec2,size:-1},{name:x,type:float,size:4},{name:y,type:float,size:4}]}
|
||||
|
|
@ -1 +1 @@
|
|||
{fields:[{name:elevation,type:float,size:4},{name:health,type:float,size:4},{name:rotation,type:float,size:4},{name:shield,type:float,size:4},{name:stack,type:mindustry.type.ItemStack,size:-1},{name:statuses,type:arc.struct.Array<mindustry.entities.units.StatusEntry>,size:-1},{name:team,type:mindustry.game.Team,size:-1},{name:type,type:mindustry.type.UnitType,size:-1},{name:vel,type:arc.math.geom.Vec2,size:-1},{name:x,type:float,size:4},{name:y,type:float,size:4}]}
|
||||
{fields:[{name:armor,type:float,size:4},{name:elevation,type:float,size:4},{name:health,type:float,size:4},{name:rotation,type:float,size:4},{name:shield,type:float,size:4},{name:spawnedByCore,type:boolean,size:1},{name:stack,type:mindustry.type.ItemStack,size:-1},{name:statuses,type:arc.struct.Array<mindustry.entities.units.StatusEntry>,size:-1},{name:team,type:mindustry.game.Team,size:-1},{name:type,type:mindustry.type.UnitType,size:-1},{name:vel,type:arc.math.geom.Vec2,size:-1},{name:x,type:float,size:4},{name:y,type:float,size:4}]}
|
||||
|
|
@ -1 +0,0 @@
|
|||
{version:1,fields:[{name:armor,type:float,size:4},{name:elevation,type:float,size:4},{name:health,type:float,size:4},{name:rotation,type:float,size:4},{name:shield,type:float,size:4},{name:stack,type:mindustry.type.ItemStack,size:-1},{name:statuses,type:arc.struct.Array<mindustry.entities.units.StatusEntry>,size:-1},{name:team,type:mindustry.game.Team,size:-1},{name:type,type:mindustry.type.UnitType,size:-1},{name:vel,type:arc.math.geom.Vec2,size:-1},{name:x,type:float,size:4},{name:y,type:float,size:4}]}
|
||||
|
|
@ -1 +0,0 @@
|
|||
{version:2,fields:[{name:armor,type:float,size:4},{name:elevation,type:float,size:4},{name:health,type:float,size:4},{name:rotation,type:float,size:4},{name:shield,type:float,size:4},{name:spawnedByCore,type:boolean,size:1},{name:stack,type:mindustry.type.ItemStack,size:-1},{name:statuses,type:arc.struct.Array<mindustry.entities.units.StatusEntry>,size:-1},{name:team,type:mindustry.game.Team,size:-1},{name:type,type:mindustry.type.UnitType,size:-1},{name:vel,type:arc.math.geom.Vec2,size:-1},{name:x,type:float,size:4},{name:y,type:float,size:4}]}
|
||||
Loading…
Add table
Add a link
Reference in a new issue