diff --git a/core/src/mindustry/logic/LExecutor.java b/core/src/mindustry/logic/LExecutor.java index 2e87d6c84b..926b8141f4 100644 --- a/core/src/mindustry/logic/LExecutor.java +++ b/core/src/mindustry/logic/LExecutor.java @@ -60,6 +60,8 @@ public class LExecutor{ //yes, this is a minor memory leak, but it's probably not significant enough to matter protected IntFloatMap unitTimeouts = new IntFloatMap(); + //lookup variable by name, lazy init. + protected ObjectIntMap nameMap; boolean timeoutDone(Unit unit, float delay){ return Time.time >= unitTimeouts.get(unit.id) + delay; @@ -123,6 +125,16 @@ public class LExecutor{ return index < 0 ? logicVars.get(-index) : vars[index]; } + public @Nullable Var optionalVar(String name){ + if(nameMap == null){ + nameMap = new ObjectIntMap<>(); + for(int i = 0; i < vars.length; i++){ + nameMap.put(vars[i].name, i); + } + } + return optionalVar(nameMap.get(name, -1)); + } + /** @return a Var from this processor, never a global constant. May be null if out of bounds. */ public @Nullable Var optionalVar(int index){ return index < 0 || index >= vars.length ? null : vars[index]; @@ -133,6 +145,13 @@ public class LExecutor{ return var(index).isobj && o instanceof Building building ? building : null; } + public @Nullable Building accissibleBuilding(int index){ + Building res = building(index); + if(res == null || privileged) return res; + if(res.block.privileged || res.team != team) return null; + return res; + } + public @Nullable Object obj(int index){ Object o = var(index).objval; return var(index).isobj ? o : null; @@ -331,8 +350,8 @@ public class LExecutor{ cache.found = false; exec.setnum(outFound, 0); } - - if(res != null && res.build != null && + + if(res != null && res.build != null && (unit.within(res.build.x, res.build.y, Math.max(unit.range(), buildingRange)) || res.build.team == exec.team)){ cache.build = res.build; exec.setobj(outBuild, res.build); @@ -660,12 +679,18 @@ public class LExecutor{ @Override public void run(LExecutor exec){ - int address = exec.numi(position); - Building from = exec.building(target); - - if(from instanceof MemoryBuild mem && (exec.privileged || from.team == exec.team)){ - + Building from = exec.accissibleBuilding(target); + if(from instanceof MemoryBuild mem){ + int address = exec.numi(position); exec.setnum(output, address < 0 || address >= mem.memory.length ? 0 : mem.memory[address]); + }else if(from instanceof LogicBuild logic && exec.obj(position) instanceof String name){ + Var fromVar = logic.executor.optionalVar(name); + Var toVar = exec.var(output); + if(fromVar != null && !toVar.constant){ + toVar.objval = fromVar.objval; + toVar.numval = fromVar.numval; + toVar.isobj = fromVar.isobj; + } } } } @@ -684,11 +709,20 @@ public class LExecutor{ @Override public void run(LExecutor exec){ - int address = exec.numi(position); - Building from = exec.building(target); - - if(from instanceof MemoryBuild mem && (exec.privileged || from.team == exec.team) && address >= 0 && address < mem.memory.length){ - mem.memory[address] = exec.num(value); + Building from = exec.accissibleBuilding(target); + if(from instanceof MemoryBuild mem){ + int address = exec.numi(position); + if(address >= 0 && address < mem.memory.length){ + mem.memory[address] = exec.num(value); + } + }else if(from instanceof LogicBuild logic && exec.obj(position) instanceof String name){ + Var toVar = logic.executor.optionalVar(name); + Var fromVar = exec.var(value); + if(toVar != null && !toVar.constant){ + toVar.objval = fromVar.objval; + toVar.numval = fromVar.numval; + toVar.isobj = fromVar.isobj; + } } } } @@ -989,7 +1023,7 @@ public class LExecutor{ //graphics on headless servers are useless. if(Vars.headless) return; - if(exec.building(target) instanceof LogicDisplayBuild d && (d.team == exec.team || exec.privileged)){ + if(exec.accissibleBuilding(target) instanceof LogicDisplayBuild d){ if(d.commands.size + exec.graphicsBuffer.size < maxDisplayBuffer){ for(int i = 0; i < exec.graphicsBuffer.size; i++){ d.commands.addLast(exec.graphicsBuffer.items[i]); @@ -1058,7 +1092,7 @@ public class LExecutor{ @Override public void run(LExecutor exec){ - if(exec.building(target) instanceof MessageBuild d && (d.team == exec.team || exec.privileged)){ + if(exec.accissibleBuilding(target) instanceof MessageBuild d){ d.message.setLength(0); d.message.append(exec.textBuffer, 0, Math.min(exec.textBuffer.length(), maxTextBuffer));