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{
|
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){
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
|
|
||||||
|
|
@ -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{
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue