Merge branch 'master' into pr-readwrite

This commit is contained in:
Anuken
2025-02-09 00:38:18 -05:00
committed by GitHub
432 changed files with 20155 additions and 10789 deletions

View File

@@ -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;