mirror of
https://github.com/Anuken/Mindustry.git
synced 2025-12-06 02:40:23 -08:00
Save unit variables in processors
This commit is contained in:
parent
ea6d794c36
commit
635027bb81
11 changed files with 76 additions and 18 deletions
22
core/src/mindustry/entities/comp/BuildingTetherComp.java
Normal file
22
core/src/mindustry/entities/comp/BuildingTetherComp.java
Normal 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());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -86,7 +86,11 @@ public class SaveIO{
|
|||
try{
|
||||
readHeader(stream);
|
||||
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();
|
||||
return meta;
|
||||
}catch(IOException e){
|
||||
|
|
@ -158,6 +162,8 @@ public class SaveIO{
|
|||
int version = stream.readInt();
|
||||
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);
|
||||
Events.fire(new SaveLoadEvent());
|
||||
}catch(Throwable e){
|
||||
|
|
|
|||
|
|
@ -81,6 +81,9 @@ public class TypeIO{
|
|||
}else if(object instanceof Building b){
|
||||
write.b(12);
|
||||
write.i(b.pos());
|
||||
}else if(object instanceof BuildingBox b){
|
||||
write.b(12);
|
||||
write.i(b.pos);
|
||||
}else if(object instanceof LAccess l){
|
||||
write.b((byte)13);
|
||||
write.s(l.ordinal());
|
||||
|
|
@ -91,15 +94,18 @@ public class TypeIO{
|
|||
}else if(object instanceof UnitCommand c){
|
||||
write.b((byte)15);
|
||||
write.b(c.ordinal());
|
||||
}else if(object instanceof BuildingBox b){
|
||||
write.b(12);
|
||||
write.i(b.pos);
|
||||
}else if(object instanceof boolean[] b){
|
||||
write.b(16);
|
||||
write.i(b.length);
|
||||
for(boolean bool : b){
|
||||
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{
|
||||
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 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 17: return !box ? Groups.unit.getByID(read.i()) : new UnitBox(read.i());
|
||||
default: throw new IllegalArgumentException("Unknown object type: " + type);
|
||||
}
|
||||
}
|
||||
|
|
@ -656,5 +663,22 @@ public class TypeIO{
|
|||
public BuildingBox(int 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ public class LAssembler{
|
|||
public LAssembler(){
|
||||
//instruction counter
|
||||
putVar("@counter").value = 0;
|
||||
//unix timestamp
|
||||
//timestamp
|
||||
putConst("@time", 0);
|
||||
//currently controlled unit
|
||||
putConst("@unit", null);
|
||||
|
|
|
|||
|
|
@ -208,7 +208,7 @@ public class LExecutor{
|
|||
}
|
||||
|
||||
//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);
|
||||
|
||||
if(seq != null && seq.any()){
|
||||
|
|
@ -222,7 +222,7 @@ public class LExecutor{
|
|||
//no units of this type found
|
||||
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
|
||||
exec.setconst(varUnit, u);
|
||||
}else{
|
||||
|
|
|
|||
|
|
@ -836,7 +836,7 @@ public class LStatements{
|
|||
i.left();
|
||||
int c = 0;
|
||||
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, () -> {
|
||||
type = "@" + item.name;
|
||||
field.setText(type);
|
||||
|
|
|
|||
|
|
@ -64,6 +64,8 @@ public class UnitType extends UnlockableContent{
|
|||
public boolean targetAir = true, targetGround = true;
|
||||
public boolean faceTarget = true, rotateShooting = true, isCounted = true, lowAltitude = false, circleTarget = false;
|
||||
public boolean canBoost = false;
|
||||
public boolean logicControllable = true;
|
||||
public boolean allowedInPayloads = true;
|
||||
public boolean destructibleWreck = true;
|
||||
public float groundLayer = Layer.groundUnit;
|
||||
public float payloadCapacity = 8;
|
||||
|
|
|
|||
|
|
@ -75,8 +75,8 @@ public class PayloadConveyor extends Block{
|
|||
public int step = -1, stepAccepted = -1;
|
||||
|
||||
@Override
|
||||
public boolean canControlSelect(Unit player){
|
||||
return this.item == null && !player.spawnedByCore && player.hitSize / tilesize <= payloadLimit && player.tileOn() != null && player.tileOn().build == this;
|
||||
public boolean canControlSelect(Unit unit){
|
||||
return this.item == null && unit.type.allowedInPayloads && !unit.spawnedByCore && unit.hitSize / tilesize <= payloadLimit && unit.tileOn() != null && unit.tileOn().build == this;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -525,19 +525,18 @@ public class LogicBlock extends Block{
|
|||
write.b(compressed);
|
||||
|
||||
//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);
|
||||
for(int i = 0; i < executor.vars.length; 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.str(v.name);
|
||||
|
||||
Object value = v.isobj ? v.objval : v.numval;
|
||||
if(value instanceof Unit) value = null; //do not save units.
|
||||
TypeIO.writeObject(write, value);
|
||||
}
|
||||
|
||||
|
|
@ -585,8 +584,12 @@ public class LogicBlock extends Block{
|
|||
//load up the variables that were stored
|
||||
for(int i = 0; i < varcount; 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];
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
|
|||
|
|
@ -81,8 +81,8 @@ public class PayloadBlock extends Block{
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean canControlSelect(Unit player){
|
||||
return !player.spawnedByCore && this.payload == null && acceptUnitPayload(player) && player.tileOn() != null && player.tileOn().build == this;
|
||||
public boolean canControlSelect(Unit unit){
|
||||
return !unit.spawnedByCore && unit.type.allowedInPayloads && this.payload == null && acceptUnitPayload(unit) && unit.tileOn() != null && unit.tileOn().build == this;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -87,7 +87,8 @@ public class PayloadDeconstructor extends PayloadBlock{
|
|||
|
||||
@Override
|
||||
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
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue