Save unit variables in processors

This commit is contained in:
Anuken 2021-11-29 10:57:42 -05:00
parent ea6d794c36
commit 635027bb81
11 changed files with 76 additions and 18 deletions

View file

@ -0,0 +1,22 @@
package mindustry.entities.comp;
import mindustry.annotations.Annotations.*;
import mindustry.game.*;
import mindustry.gen.*;
import mindustry.type.*;
/** A unit that depends on a building's existence; if that building is removed, it despawns. */
@Component
abstract class BuildingTetherComp implements Unitc{
@Import UnitType type;
@Import Team team;
public Building building;
@Override
public void update(){
if(building == null || !building.isValid() || building.team != team){
Call.unitDespawn(self());
}
}
}

View file

@ -86,7 +86,11 @@ public class SaveIO{
try{ try{
readHeader(stream); readHeader(stream);
int version = stream.readInt(); int version = stream.readInt();
SaveMeta meta = versions.get(version).getMeta(stream); SaveVersion ver = versions.get(version);
if(ver == null) throw new IOException("Unknown save version: " + version + ". Are you trying to load a save from a newer version?");
SaveMeta meta = ver.getMeta(stream);
stream.close(); stream.close();
return meta; return meta;
}catch(IOException e){ }catch(IOException e){
@ -158,6 +162,8 @@ public class SaveIO{
int version = stream.readInt(); int version = stream.readInt();
SaveVersion ver = versions.get(version); SaveVersion ver = versions.get(version);
if(ver == null) throw new IOException("Unknown save version: " + version + ". Are you trying to load a save from a newer version?");
ver.read(stream, counter, context); ver.read(stream, counter, context);
Events.fire(new SaveLoadEvent()); Events.fire(new SaveLoadEvent());
}catch(Throwable e){ }catch(Throwable e){

View file

@ -81,6 +81,9 @@ public class TypeIO{
}else if(object instanceof Building b){ }else if(object instanceof Building b){
write.b(12); write.b(12);
write.i(b.pos()); write.i(b.pos());
}else if(object instanceof BuildingBox b){
write.b(12);
write.i(b.pos);
}else if(object instanceof LAccess l){ }else if(object instanceof LAccess l){
write.b((byte)13); write.b((byte)13);
write.s(l.ordinal()); write.s(l.ordinal());
@ -91,15 +94,18 @@ public class TypeIO{
}else if(object instanceof UnitCommand c){ }else if(object instanceof UnitCommand c){
write.b((byte)15); write.b((byte)15);
write.b(c.ordinal()); write.b(c.ordinal());
}else if(object instanceof BuildingBox b){
write.b(12);
write.i(b.pos);
}else if(object instanceof boolean[] b){ }else if(object instanceof boolean[] b){
write.b(16); write.b(16);
write.i(b.length); write.i(b.length);
for(boolean bool : b){ for(boolean bool : b){
write.bool(bool); write.bool(bool);
} }
}else if(object instanceof Unit u){
write.b(17);
write.i(u.id);
}else if(object instanceof UnitBox u){
write.b(17);
write.i(u.id);
}else{ }else{
throw new IllegalArgumentException("Unknown object type: " + object.getClass()); throw new IllegalArgumentException("Unknown object type: " + object.getClass());
} }
@ -132,6 +138,7 @@ public class TypeIO{
case 14: int blen = read.i(); byte[] bytes = new byte[blen]; read.b(bytes); return bytes; case 14: int blen = read.i(); byte[] bytes = new byte[blen]; read.b(bytes); return bytes;
case 15: return UnitCommand.all[read.b()]; case 15: return UnitCommand.all[read.b()];
case 16: int boollen = read.i(); boolean[] bools = new boolean[boollen]; for(int i = 0; i < boollen; i ++) bools[i] = read.bool(); return bools; case 16: int boollen = read.i(); boolean[] bools = new boolean[boollen]; for(int i = 0; i < boollen; i ++) bools[i] = read.bool(); return bools;
case 17: return !box ? Groups.unit.getByID(read.i()) : new UnitBox(read.i());
default: throw new IllegalArgumentException("Unknown object type: " + type); default: throw new IllegalArgumentException("Unknown object type: " + type);
} }
} }
@ -656,5 +663,22 @@ public class TypeIO{
public BuildingBox(int pos){ public BuildingBox(int pos){
this.pos = pos; this.pos = pos;
} }
public Building unbox(){
return world.build(pos);
}
}
/** Represents a unit that has not been resolved yet. TODO unimplemented / unused*/
public static class UnitBox{
public int id;
public UnitBox(int id){
this.id = id;
}
public Unit unbox(){
return Groups.unit.getByID(id);
}
} }
} }

View file

@ -22,7 +22,7 @@ public class LAssembler{
public LAssembler(){ public LAssembler(){
//instruction counter //instruction counter
putVar("@counter").value = 0; putVar("@counter").value = 0;
//unix timestamp //timestamp
putConst("@time", 0); putConst("@time", 0);
//currently controlled unit //currently controlled unit
putConst("@unit", null); putConst("@unit", null);

View file

@ -208,7 +208,7 @@ public class LExecutor{
} }
//binding to `null` was previously possible, but was too powerful and exploitable //binding to `null` was previously possible, but was too powerful and exploitable
if(exec.obj(type) instanceof UnitType type){ if(exec.obj(type) instanceof UnitType type && type.logicControllable){
Seq<Unit> seq = exec.team.data().unitCache(type); Seq<Unit> seq = exec.team.data().unitCache(type);
if(seq != null && seq.any()){ if(seq != null && seq.any()){
@ -222,7 +222,7 @@ public class LExecutor{
//no units of this type found //no units of this type found
exec.setconst(varUnit, null); exec.setconst(varUnit, null);
} }
}else if(exec.obj(type) instanceof Unit u && u.team == exec.team){ }else if(exec.obj(type) instanceof Unit u && u.team == exec.team && u.type.logicControllable){
//bind to specific unit object //bind to specific unit object
exec.setconst(varUnit, u); exec.setconst(varUnit, u);
}else{ }else{

View file

@ -836,7 +836,7 @@ public class LStatements{
i.left(); i.left();
int c = 0; int c = 0;
for(UnitType item : Vars.content.units()){ for(UnitType item : Vars.content.units()){
if(!item.unlockedNow() || item.isHidden()) continue; if(!item.unlockedNow() || item.isHidden() || !item.logicControllable) continue;
i.button(new TextureRegionDrawable(item.uiIcon), Styles.cleari, iconSmall, () -> { i.button(new TextureRegionDrawable(item.uiIcon), Styles.cleari, iconSmall, () -> {
type = "@" + item.name; type = "@" + item.name;
field.setText(type); field.setText(type);

View file

@ -64,6 +64,8 @@ public class UnitType extends UnlockableContent{
public boolean targetAir = true, targetGround = true; public boolean targetAir = true, targetGround = true;
public boolean faceTarget = true, rotateShooting = true, isCounted = true, lowAltitude = false, circleTarget = false; public boolean faceTarget = true, rotateShooting = true, isCounted = true, lowAltitude = false, circleTarget = false;
public boolean canBoost = false; public boolean canBoost = false;
public boolean logicControllable = true;
public boolean allowedInPayloads = true;
public boolean destructibleWreck = true; public boolean destructibleWreck = true;
public float groundLayer = Layer.groundUnit; public float groundLayer = Layer.groundUnit;
public float payloadCapacity = 8; public float payloadCapacity = 8;

View file

@ -75,8 +75,8 @@ public class PayloadConveyor extends Block{
public int step = -1, stepAccepted = -1; public int step = -1, stepAccepted = -1;
@Override @Override
public boolean canControlSelect(Unit player){ public boolean canControlSelect(Unit unit){
return this.item == null && !player.spawnedByCore && player.hitSize / tilesize <= payloadLimit && player.tileOn() != null && player.tileOn().build == this; return this.item == null && unit.type.allowedInPayloads && !unit.spawnedByCore && unit.hitSize / tilesize <= payloadLimit && unit.tileOn() != null && unit.tileOn().build == this;
} }
@Override @Override

View file

@ -525,19 +525,18 @@ public class LogicBlock extends Block{
write.b(compressed); write.b(compressed);
//write only the non-constant variables //write only the non-constant variables
int count = Structs.count(executor.vars, v -> !v.constant); int count = Structs.count(executor.vars, v -> !v.constant || v == executor.vars[LExecutor.varUnit]);
write.i(count); write.i(count);
for(int i = 0; i < executor.vars.length; i++){ for(int i = 0; i < executor.vars.length; i++){
Var v = executor.vars[i]; Var v = executor.vars[i];
if(v.constant) continue; if(v.constant && i != LExecutor.varUnit) continue;
//write the name and the object value //write the name and the object value
write.str(v.name); write.str(v.name);
Object value = v.isobj ? v.objval : v.numval; Object value = v.isobj ? v.objval : v.numval;
if(value instanceof Unit) value = null; //do not save units.
TypeIO.writeObject(write, value); TypeIO.writeObject(write, value);
} }
@ -585,8 +584,12 @@ public class LogicBlock extends Block{
//load up the variables that were stored //load up the variables that were stored
for(int i = 0; i < varcount; i++){ for(int i = 0; i < varcount; i++){
BVar dest = asm.getVar(names[i]); BVar dest = asm.getVar(names[i]);
if(dest != null && !dest.constant){
dest.value = values[i] instanceof BuildingBox box ? world.build(box.pos) : values[i]; if(dest != null && (!dest.constant || dest.id == LExecutor.varUnit)){
dest.value =
values[i] instanceof BuildingBox box ? box.unbox() :
values[i] instanceof UnitBox box ? box.unbox() :
values[i];
} }
} }
}); });

View file

@ -81,8 +81,8 @@ public class PayloadBlock extends Block{
} }
@Override @Override
public boolean canControlSelect(Unit player){ public boolean canControlSelect(Unit unit){
return !player.spawnedByCore && this.payload == null && acceptUnitPayload(player) && player.tileOn() != null && player.tileOn().build == this; return !unit.spawnedByCore && unit.type.allowedInPayloads && this.payload == null && acceptUnitPayload(unit) && unit.tileOn() != null && unit.tileOn().build == this;
} }
@Override @Override

View file

@ -87,7 +87,8 @@ public class PayloadDeconstructor extends PayloadBlock{
@Override @Override
public boolean acceptUnitPayload(Unit unit){ public boolean acceptUnitPayload(Unit unit){
return payload == null && deconstructing == null && !unit.spawnedByCore && unit.type.getTotalRequirements().length > 0 && unit.hitSize / tilesize <= maxPayloadSize; return payload == null && deconstructing == null && unit.type.allowedInPayloads && !unit.spawnedByCore
&& unit.type.getTotalRequirements().length > 0 && unit.hitSize / tilesize <= maxPayloadSize;
} }
@Override @Override