Merge branch 'master' into pr-readwrite
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
package mindustry.logic;
|
||||
|
||||
import arc.*;
|
||||
import arc.audio.*;
|
||||
import arc.graphics.*;
|
||||
import arc.math.*;
|
||||
import arc.math.geom.*;
|
||||
@@ -41,13 +42,12 @@ public class LExecutor{
|
||||
maxDisplayBuffer = 1024,
|
||||
maxTextBuffer = 400;
|
||||
|
||||
|
||||
public LInstruction[] instructions = {};
|
||||
/** Non-constant variables used for network sync */
|
||||
public LVar[] vars = {};
|
||||
|
||||
|
||||
public LVar counter, unit, thisv, ipt;
|
||||
|
||||
|
||||
public int[] binds;
|
||||
public boolean yield;
|
||||
|
||||
@@ -569,7 +569,7 @@ public class LExecutor{
|
||||
int address = position.numi();
|
||||
Building from = target.building();
|
||||
|
||||
if(from instanceof MemoryBuild mem && (exec.privileged || from.team == exec.team)){
|
||||
if(from instanceof MemoryBuild mem && (exec.privileged || (from.team == exec.team && !mem.block.privileged))){
|
||||
output.setnum(address < 0 || address >= mem.memory.length ? 0 : mem.memory[address]);
|
||||
}else if(from instanceof LogicBuild logic && (exec.privileged || from.team == exec.team) && position.isobj && position.objval instanceof String name){
|
||||
LVar fromVar = logic.executor.optionalVar(name);
|
||||
@@ -693,7 +693,7 @@ public class LExecutor{
|
||||
LogicAI ai = null;
|
||||
|
||||
if(base instanceof Ranged r && (exec.privileged || r.team() == exec.team) &&
|
||||
(base instanceof Building || (ai = UnitControlI.checkLogicAI(exec, base)) != null)){ //must be a building or a controllable unit
|
||||
((base instanceof Building b && (!b.block.privileged || exec.privileged)) || (ai = UnitControlI.checkLogicAI(exec, base)) != null)){ //must be a building or a controllable unit
|
||||
float range = r.range();
|
||||
|
||||
Healthc targeted;
|
||||
@@ -997,8 +997,8 @@ public class LExecutor{
|
||||
exec.textBuffer.append(strValue);
|
||||
}else{
|
||||
//display integer version when possible
|
||||
if(Math.abs(value.numval - (long)value.numval) < 0.00001){
|
||||
exec.textBuffer.append((long)value.numval);
|
||||
if(Math.abs(value.numval - Math.round(value.numval)) < 0.00001){
|
||||
exec.textBuffer.append(Math.round(value.numval));
|
||||
}else{
|
||||
exec.textBuffer.append(value.numval);
|
||||
}
|
||||
@@ -1009,7 +1009,6 @@ public class LExecutor{
|
||||
return
|
||||
obj == null ? "null" :
|
||||
obj instanceof String s ? s :
|
||||
obj == Blocks.stoneWall ? "solid" : //special alias
|
||||
obj instanceof MappableContent content ? content.name :
|
||||
obj instanceof Content ? "[content]" :
|
||||
obj instanceof Building build ? build.block.name :
|
||||
@@ -1020,6 +1019,29 @@ public class LExecutor{
|
||||
}
|
||||
}
|
||||
|
||||
public static class PrintCharI implements LInstruction{
|
||||
public LVar value;
|
||||
|
||||
public PrintCharI(LVar value){
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
PrintCharI(){}
|
||||
|
||||
@Override
|
||||
public void run(LExecutor exec){
|
||||
|
||||
if(exec.textBuffer.length() >= maxTextBuffer) return;
|
||||
if(value.isobj){
|
||||
if(!(value.objval instanceof UnlockableContent cont)) return;
|
||||
exec.textBuffer.append((char)cont.emojiChar());
|
||||
return;
|
||||
}
|
||||
|
||||
exec.textBuffer.append((char)Math.floor(value.numval));
|
||||
}
|
||||
}
|
||||
|
||||
public static class FormatI implements LInstruction{
|
||||
public LVar value;
|
||||
|
||||
@@ -1059,8 +1081,8 @@ public class LExecutor{
|
||||
exec.textBuffer.replace(placeholderIndex, placeholderIndex + 3, strValue);
|
||||
}else{
|
||||
//display integer version when possible
|
||||
if(Math.abs(value.numval - (long)value.numval) < 0.00001){
|
||||
exec.textBuffer.replace(placeholderIndex, placeholderIndex + 3, (long)value.numval + "");
|
||||
if(Math.abs(value.numval - Math.round(value.numval)) < 0.00001){
|
||||
exec.textBuffer.replace(placeholderIndex, placeholderIndex + 3, Math.round(value.numval) + "");
|
||||
}else{
|
||||
exec.textBuffer.replace(placeholderIndex, placeholderIndex + 3, value.numval + "");
|
||||
}
|
||||
@@ -1081,7 +1103,7 @@ public class LExecutor{
|
||||
@Override
|
||||
public void run(LExecutor exec){
|
||||
|
||||
if(target.building() instanceof MessageBuild d && (d.team == exec.team || exec.privileged)){
|
||||
if(target.building() instanceof MessageBuild d && (exec.privileged || (d.team == exec.team && !d.block.privileged))){
|
||||
|
||||
d.message.setLength(0);
|
||||
d.message.append(exec.textBuffer, 0, Math.min(exec.textBuffer.length(), maxTextBuffer));
|
||||
@@ -1273,7 +1295,8 @@ public class LExecutor{
|
||||
result.setobj(units == null || i < 0 || i >= units.size ? null : units.get(i));
|
||||
}
|
||||
}
|
||||
case player -> result.setobj(i < 0 || i >= data.players.size ? null : data.players.get(i).unit());
|
||||
case player -> result.setobj(i < 0 || i >= data.players.size ? null :
|
||||
data.players.get(i).unit() instanceof BlockUnitc block ? block.tile() : data.players.get(i).unit());
|
||||
case core -> result.setobj(i < 0 || i >= data.cores.size ? null : data.cores.get(i));
|
||||
case build -> {
|
||||
Block block = extra.obj() instanceof Block b ? b : null;
|
||||
@@ -1326,7 +1349,7 @@ public class LExecutor{
|
||||
|
||||
@Override
|
||||
public void run(LExecutor exec){
|
||||
Tile tile = world.tile(x.numi(), y.numi());
|
||||
Tile tile = world.tile(Mathf.round(x.numf()), Mathf.round(y.numf()));
|
||||
if(tile == null){
|
||||
dest.setobj(null);
|
||||
}else{
|
||||
@@ -1380,7 +1403,7 @@ public class LExecutor{
|
||||
if(t == null) t = Team.derelict;
|
||||
|
||||
if(tile.block() != b || tile.team() != t){
|
||||
tile.setBlock(b, t, Mathf.clamp(rotation.numi(), 0, 3));
|
||||
tile.setNet(b, t, Mathf.clamp(rotation.numi(), 0, 3));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1411,7 +1434,7 @@ public class LExecutor{
|
||||
|
||||
Team t = team.team();
|
||||
|
||||
if(type.obj() instanceof UnitType type && !type.hidden && t != null && Units.canCreate(t, type)){
|
||||
if(type.obj() instanceof UnitType type && !type.internal && !type.hidden && t != null && Units.canCreate(t, type)){
|
||||
//random offset to prevent stacking
|
||||
var unit = type.spawn(t, World.unconv(x.numf()) + Mathf.range(0.01f), World.unconv(y.numf()) + Mathf.range(0.01f));
|
||||
spawner.spawnEffect(unit, rotation.numf());
|
||||
@@ -1520,6 +1543,7 @@ public class LExecutor{
|
||||
case dropZoneRadius -> state.rules.dropZoneRadius = value.numf() * 8f;
|
||||
case unitCap -> state.rules.unitCap = Math.max(value.numi(), 0);
|
||||
case lighting -> state.rules.lighting = value.bool();
|
||||
case canGameOver -> state.rules.canGameOver = value.bool();
|
||||
case mapArea -> {
|
||||
int x = p1.numi(), y = p2.numi(), w = p3.numi(), h = p4.numi();
|
||||
if(!checkMapArea(x, y, w, h, false)){
|
||||
@@ -1546,7 +1570,7 @@ public class LExecutor{
|
||||
state.rules.bannedUnits.remove(u);
|
||||
}
|
||||
}
|
||||
case unitHealth, unitBuildSpeed, unitCost, unitDamage, blockHealth, blockDamage, buildSpeed, rtsMinSquad, rtsMinWeight -> {
|
||||
case unitHealth, unitBuildSpeed, unitMineSpeed, unitCost, unitDamage, blockHealth, blockDamage, buildSpeed, rtsMinSquad, rtsMinWeight -> {
|
||||
Team team = p1.team();
|
||||
if(team != null){
|
||||
float num = value.numf();
|
||||
@@ -1554,6 +1578,7 @@ public class LExecutor{
|
||||
case buildSpeed -> team.rules().buildSpeedMultiplier = Mathf.clamp(num, 0.001f, 50f);
|
||||
case unitHealth -> team.rules().unitHealthMultiplier = Math.max(num, 0.001f);
|
||||
case unitBuildSpeed -> team.rules().unitBuildSpeedMultiplier = Mathf.clamp(num, 0f, 50f);
|
||||
case unitMineSpeed -> team.rules().unitMineSpeedMultiplier = Math.max(num, 0f);
|
||||
case unitCost -> team.rules().unitCostMultiplier = Math.max(num, 0f);
|
||||
case unitDamage -> team.rules().unitDamageMultiplier = Math.max(num, 0f);
|
||||
case blockHealth -> team.rules().blockHealthMultiplier = Math.max(num, 0.001f);
|
||||
@@ -1631,7 +1656,7 @@ public class LExecutor{
|
||||
public void run(LExecutor exec){
|
||||
//set default to success
|
||||
outSuccess.setnum(1);
|
||||
if(headless && type != MessageType.mission) {
|
||||
if(headless && type != MessageType.mission){
|
||||
exec.textBuffer.setLength(0);
|
||||
return;
|
||||
}
|
||||
@@ -1641,8 +1666,14 @@ public class LExecutor{
|
||||
type == MessageType.notify && ui.hudfrag.hasToast() ||
|
||||
type == MessageType.toast && ui.hasAnnouncement()
|
||||
){
|
||||
//set outSuccess=false to let user retry.
|
||||
outSuccess.setnum(0);
|
||||
//backwards compatibility; if it is @wait, block execution
|
||||
if(outSuccess == logicVars.waitVar()){
|
||||
exec.counter.numval--;
|
||||
exec.yield = true;
|
||||
}else{
|
||||
//set outSuccess=false to let user retry.
|
||||
outSuccess.setnum(0);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1727,7 +1758,7 @@ public class LExecutor{
|
||||
public static void logicExplosion(Team team, float x, float y, float radius, float damage, boolean air, boolean ground, boolean pierce, boolean effect){
|
||||
if(damage < 0f) return;
|
||||
|
||||
Damage.damage(team, x, y, radius, damage, pierce, air, ground);
|
||||
Damage.damage(team, x, y, radius, damage, pierce, air, ground, true, null);
|
||||
if(effect){
|
||||
if(pierce){
|
||||
Fx.spawnShockwave.at(x, y, World.conv(radius));
|
||||
@@ -1942,6 +1973,37 @@ public class LExecutor{
|
||||
}
|
||||
}
|
||||
|
||||
public static class PlaySoundI implements LInstruction{
|
||||
public boolean positional;
|
||||
public LVar id, volume, pitch, pan, x, y, limit;
|
||||
|
||||
public PlaySoundI(){
|
||||
}
|
||||
|
||||
public PlaySoundI(boolean positional, LVar id, LVar volume, LVar pitch, LVar pan, LVar x, LVar y, LVar limit){
|
||||
this.positional = positional;
|
||||
this.id = id;
|
||||
this.volume = volume;
|
||||
this.pitch = pitch;
|
||||
this.pan = pan;
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.limit = limit;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run(LExecutor exec){
|
||||
Sound sound = Sounds.getSound(id.numi());
|
||||
if(sound == null || sound == Sounds.swish) sound = Sounds.none; //no.
|
||||
|
||||
if(positional){
|
||||
sound.at(World.unconv(x.numf()), World.unconv(y.numf()), pitch.numf(), Math.min(volume.numf(), 2f), limit.bool());
|
||||
}else{
|
||||
sound.play(Math.min(volume.numf() * (Core.settings.getInt("sfxvol") / 100f), 2f), pitch.numf(), pan.numf(), false, limit.bool());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class SetMarkerI implements LInstruction{
|
||||
public LMarkerControl type = LMarkerControl.pos;
|
||||
public LVar id, p1, p2, p3;
|
||||
|
||||
Reference in New Issue
Block a user