mirror of
https://github.com/Anuken/Mindustry.git
synced 2025-07-14 09:47:24 +07:00
Object sense support / Bugfixes
This commit is contained in:
@ -114,7 +114,7 @@ mod.disable = Disable
|
|||||||
mod.content = Content:
|
mod.content = Content:
|
||||||
mod.delete.error = Unable to delete mod. File may be in use.
|
mod.delete.error = Unable to delete mod. File may be in use.
|
||||||
mod.requiresversion = [scarlet]Requires min game version: [accent]{0}
|
mod.requiresversion = [scarlet]Requires min game version: [accent]{0}
|
||||||
mod.outdated = [scarlet]Not compatible with V6 (no min-game-version: 105)
|
mod.outdated = [scarlet]Not compatible with V6 (no minGameVersion: 105)
|
||||||
mod.missingdependencies = [scarlet]Missing dependencies: {0}
|
mod.missingdependencies = [scarlet]Missing dependencies: {0}
|
||||||
mod.erroredcontent = [scarlet]Content Errors
|
mod.erroredcontent = [scarlet]Content Errors
|
||||||
mod.errors = Errors have occurred loading content.
|
mod.errors = Errors have occurred loading content.
|
||||||
|
@ -78,6 +78,8 @@ public class Vars implements Loadable{
|
|||||||
public static final float miningRange = 70f;
|
public static final float miningRange = 70f;
|
||||||
/** range for building */
|
/** range for building */
|
||||||
public static final float buildingRange = 220f;
|
public static final float buildingRange = 220f;
|
||||||
|
/** range for moving items */
|
||||||
|
public static final float itemTransferRange = 220f;
|
||||||
/** duration of time between turns in ticks */
|
/** duration of time between turns in ticks */
|
||||||
public static final float turnDuration = 20 * Time.toMinutes;
|
public static final float turnDuration = 20 * Time.toMinutes;
|
||||||
/** turns needed to destroy a sector completely */
|
/** turns needed to destroy a sector completely */
|
||||||
|
@ -1226,6 +1226,13 @@ abstract class BuildingComp implements Posc, Teamc, Healthc, Buildingc, Timerc,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object senseObject(LAccess sensor){
|
||||||
|
if(sensor == LAccess.type) return block;
|
||||||
|
|
||||||
|
return noSensed;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public double sense(Content content){
|
public double sense(Content content){
|
||||||
if(content instanceof Item && items != null) return items.get((Item)content);
|
if(content instanceof Item && items != null) return items.get((Item)content);
|
||||||
|
@ -85,6 +85,13 @@ abstract class UnitComp implements Healthc, Physicsc, Hitboxc, Statusc, Teamc, I
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object senseObject(LAccess sensor){
|
||||||
|
if(sensor == LAccess.type) return type;
|
||||||
|
|
||||||
|
return noSensed;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public double sense(Content content){
|
public double sense(Content content){
|
||||||
if(content == stack().item) return stack().amount;
|
if(content == stack().item) return stack().amount;
|
||||||
|
@ -161,7 +161,7 @@ public class OverlayRenderer{
|
|||||||
Draw.reset();
|
Draw.reset();
|
||||||
|
|
||||||
Building tile = world.buildWorld(v.x, v.y);
|
Building tile = world.buildWorld(v.x, v.y);
|
||||||
if(tile != null && tile.interactable(player.team()) && tile.acceptStack(player.unit().item(), player.unit().stack.amount, player.unit()) > 0){
|
if(tile != null && tile.interactable(player.team()) && tile.acceptStack(player.unit().item(), player.unit().stack.amount, player.unit()) > 0 && player.within(tile, itemTransferRange)){
|
||||||
Lines.stroke(3f, Pal.gray);
|
Lines.stroke(3f, Pal.gray);
|
||||||
Lines.square(tile.x, tile.y, tile.block().size * tilesize / 2f + 3 + Mathf.absin(Time.time(), 5f, 1f));
|
Lines.square(tile.x, tile.y, tile.block().size * tilesize / 2f + 3 + Mathf.absin(Time.time(), 5f, 1f));
|
||||||
Lines.stroke(1f, Pal.place);
|
Lines.stroke(1f, Pal.place);
|
||||||
|
@ -75,13 +75,13 @@ public class DesktopInput extends InputHandler{
|
|||||||
});
|
});
|
||||||
|
|
||||||
group.fill(t -> {
|
group.fill(t -> {
|
||||||
t.visible(() -> Core.settings.getBool("hints") && lastSchematic != null && !selectRequests.isEmpty());
|
t.visible(() -> lastSchematic != null && !selectRequests.isEmpty());
|
||||||
t.bottom();
|
t.bottom();
|
||||||
t.table(Styles.black6, b -> {
|
t.table(Styles.black6, b -> {
|
||||||
b.defaults().left();
|
b.defaults().left();
|
||||||
b.label(() -> Core.bundle.format("schematic.flip",
|
b.label(() -> Core.bundle.format("schematic.flip",
|
||||||
Core.keybinds.get(Binding.schematic_flip_x).key.toString(),
|
Core.keybinds.get(Binding.schematic_flip_x).key.toString(),
|
||||||
Core.keybinds.get(Binding.schematic_flip_y).key.toString())).style(Styles.outlineLabel);
|
Core.keybinds.get(Binding.schematic_flip_y).key.toString())).style(Styles.outlineLabel).visible(() -> Core.settings.getBool("hints"));
|
||||||
b.row();
|
b.row();
|
||||||
b.table(a -> {
|
b.table(a -> {
|
||||||
a.button("@schematic.add", Icon.save, this::showSchematicSave).colspan(2).size(250f, 50f).disabled(f -> lastSchematic == null || lastSchematic.file != null);
|
a.button("@schematic.add", Icon.save, this::showSchematicSave).colspan(2).size(250f, 50f).disabled(f -> lastSchematic == null || lastSchematic.file != null);
|
||||||
|
@ -186,7 +186,7 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
|
|||||||
|
|
||||||
@Remote(targets = Loc.both, forward = true, called = Loc.server)
|
@Remote(targets = Loc.both, forward = true, called = Loc.server)
|
||||||
public static void transferInventory(Player player, Building tile){
|
public static void transferInventory(Player player, Building tile){
|
||||||
if(player == null || tile == null) return;
|
if(player == null || tile == null || !player.within(tile, buildingRange)) return;
|
||||||
|
|
||||||
if(net.server() && (player.unit().stack.amount <= 0 || !Units.canInteract(player, tile) ||
|
if(net.server() && (player.unit().stack.amount <= 0 || !Units.canInteract(player, tile) ||
|
||||||
!netServer.admins.allowAction(player, ActionType.depositItem, tile.tile(), action -> {
|
!netServer.admins.allowAction(player, ActionType.depositItem, tile.tile(), action -> {
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
package mindustry.logic;
|
package mindustry.logic;
|
||||||
|
|
||||||
public enum ConditionOp{
|
public enum ConditionOp{
|
||||||
equal("==", (a, b) -> Math.abs(a - b) < 0.000001),
|
equal("==", (a, b) -> Math.abs(a - b) < 0.000001, (a, b) -> a == b),
|
||||||
notEqual("not", (a, b) -> Math.abs(a - b) >= 0.000001),
|
notEqual("not", (a, b) -> Math.abs(a - b) >= 0.000001, (a, b) -> a != b),
|
||||||
lessThan("<", (a, b) -> a < b),
|
lessThan("<", (a, b) -> a < b),
|
||||||
lessThanEq("<=", (a, b) -> a <= b),
|
lessThanEq("<=", (a, b) -> a <= b),
|
||||||
greaterThan(">", (a, b) -> a > b),
|
greaterThan(">", (a, b) -> a > b),
|
||||||
@ -10,12 +10,18 @@ public enum ConditionOp{
|
|||||||
|
|
||||||
public static final ConditionOp[] all = values();
|
public static final ConditionOp[] all = values();
|
||||||
|
|
||||||
|
public final CondObjOpLambda objFunction;
|
||||||
public final CondOpLambda function;
|
public final CondOpLambda function;
|
||||||
public final String symbol;
|
public final String symbol;
|
||||||
|
|
||||||
ConditionOp(String symbol, CondOpLambda function){
|
ConditionOp(String symbol, CondOpLambda function){
|
||||||
|
this(symbol, function, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
ConditionOp(String symbol, CondOpLambda function, CondObjOpLambda objFunction){
|
||||||
this.symbol = symbol;
|
this.symbol = symbol;
|
||||||
this.function = function;
|
this.function = function;
|
||||||
|
this.objFunction = objFunction;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -23,6 +29,10 @@ public enum ConditionOp{
|
|||||||
return symbol;
|
return symbol;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface CondObjOpLambda{
|
||||||
|
boolean get(Object a, Object b);
|
||||||
|
}
|
||||||
|
|
||||||
interface CondOpLambda{
|
interface CondOpLambda{
|
||||||
boolean get(double a, double b);
|
boolean get(double a, double b);
|
||||||
}
|
}
|
||||||
|
@ -25,6 +25,7 @@ public enum LAccess{
|
|||||||
shootY,
|
shootY,
|
||||||
shooting,
|
shooting,
|
||||||
team,
|
team,
|
||||||
|
type,
|
||||||
|
|
||||||
//values with parameters are considered controllable
|
//values with parameters are considered controllable
|
||||||
enabled("to"), //"to" is standard for single parameter access
|
enabled("to"), //"to" is standard for single parameter access
|
||||||
|
@ -8,6 +8,7 @@ import mindustry.gen.*;
|
|||||||
import mindustry.logic.LExecutor.*;
|
import mindustry.logic.LExecutor.*;
|
||||||
import mindustry.logic.LStatements.*;
|
import mindustry.logic.LStatements.*;
|
||||||
import mindustry.type.*;
|
import mindustry.type.*;
|
||||||
|
import mindustry.world.*;
|
||||||
|
|
||||||
/** "Compiles" a sequence of statements into instructions. */
|
/** "Compiles" a sequence of statements into instructions. */
|
||||||
public class LAssembler{
|
public class LAssembler{
|
||||||
@ -38,6 +39,12 @@ public class LAssembler{
|
|||||||
putConst("@" + liquid.name, liquid);
|
putConst("@" + liquid.name, liquid);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for(Block block : Vars.content.blocks()){
|
||||||
|
if(block.synthetic()){
|
||||||
|
putConst("@" + block.name, block);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//store sensor constants
|
//store sensor constants
|
||||||
|
|
||||||
for(LAccess sensor : LAccess.all){
|
for(LAccess sensor : LAccess.all){
|
||||||
|
@ -255,18 +255,22 @@ public class LExecutor{
|
|||||||
Object target = exec.obj(from);
|
Object target = exec.obj(from);
|
||||||
Object sense = exec.obj(type);
|
Object sense = exec.obj(type);
|
||||||
|
|
||||||
double output = 0;
|
|
||||||
|
|
||||||
if(target instanceof Senseable){
|
if(target instanceof Senseable){
|
||||||
|
Senseable se = (Senseable)target;
|
||||||
if(sense instanceof Content){
|
if(sense instanceof Content){
|
||||||
output = ((Senseable)target).sense(((Content)sense));
|
exec.setnum(to, se.sense(((Content)sense)));
|
||||||
}else if(sense instanceof LAccess){
|
}else if(sense instanceof LAccess){
|
||||||
output = ((Senseable)target).sense(((LAccess)sense));
|
Object objOut = se.senseObject((LAccess)sense);
|
||||||
|
|
||||||
|
if(objOut == Senseable.noSensed){
|
||||||
|
//numeric output
|
||||||
|
exec.setnum(to, se.sense((LAccess)sense));
|
||||||
|
}else{
|
||||||
|
//object output
|
||||||
|
exec.setobj(to, objOut);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
exec.setnum(to, output);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -399,8 +403,18 @@ public class LExecutor{
|
|||||||
if(op.unary){
|
if(op.unary){
|
||||||
exec.setnum(dest, op.function1.get(exec.num(a)));
|
exec.setnum(dest, op.function1.get(exec.num(a)));
|
||||||
}else{
|
}else{
|
||||||
|
Var va = exec.vars[a];
|
||||||
|
Var vb = exec.vars[b];
|
||||||
|
|
||||||
|
if(op.objFunction2 != null && (va.isobj || vb.isobj)){
|
||||||
|
//use object function if provided, and one of the variables is an object
|
||||||
|
exec.setnum(dest, op.objFunction2.get(exec.obj(a), exec.obj(b)));
|
||||||
|
}else{
|
||||||
|
//otherwise use the numeric function
|
||||||
exec.setnum(dest, op.function2.get(exec.num(a), exec.num(b)));
|
exec.setnum(dest, op.function2.get(exec.num(a), exec.num(b)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -554,11 +568,24 @@ public class LExecutor{
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void run(LExecutor exec){
|
public void run(LExecutor exec){
|
||||||
if(address != -1 && op.function.get(exec.num(value), exec.num(compare))){
|
if(address != -1){
|
||||||
|
Var va = exec.vars[value];
|
||||||
|
Var vb = exec.vars[compare];
|
||||||
|
boolean cmp = false;
|
||||||
|
|
||||||
|
if(op.objFunction != null && (va.isobj || vb.isobj)){
|
||||||
|
//use object function if provided, and one of the variables is an object
|
||||||
|
cmp = op.objFunction.get(exec.obj(value), exec.obj(compare));
|
||||||
|
}else{
|
||||||
|
cmp = op.function.get(exec.num(value), exec.num(compare));
|
||||||
|
}
|
||||||
|
|
||||||
|
if(cmp){
|
||||||
exec.vars[varCounter].numval = address;
|
exec.vars[varCounter].numval = address;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//endregion
|
//endregion
|
||||||
}
|
}
|
||||||
|
@ -8,8 +8,8 @@ public enum LogicOp{
|
|||||||
mul("*", (a, b) -> a * b),
|
mul("*", (a, b) -> a * b),
|
||||||
div("/", (a, b) -> a / b),
|
div("/", (a, b) -> a / b),
|
||||||
mod("%", (a, b) -> a % b),
|
mod("%", (a, b) -> a % b),
|
||||||
equal("==", (a, b) -> Math.abs(a - b) < 0.000001 ? 1 : 0),
|
equal("==", (a, b) -> Math.abs(a - b) < 0.000001 ? 1 : 0, (a, b) -> a == b ? 1 : 0),
|
||||||
notEqual("not", (a, b) -> Math.abs(a - b) < 0.000001 ? 0 : 1),
|
notEqual("not", (a, b) -> Math.abs(a - b) < 0.000001 ? 0 : 1, (a, b) -> a != b ? 1 : 0),
|
||||||
lessThan("<", (a, b) -> a < b ? 1 : 0),
|
lessThan("<", (a, b) -> a < b ? 1 : 0),
|
||||||
lessThanEq("<=", (a, b) -> a <= b ? 1 : 0),
|
lessThanEq("<=", (a, b) -> a <= b ? 1 : 0),
|
||||||
greaterThan(">", (a, b) -> a > b ? 1 : 0),
|
greaterThan(">", (a, b) -> a > b ? 1 : 0),
|
||||||
@ -41,16 +41,22 @@ public enum LogicOp{
|
|||||||
|
|
||||||
public static final LogicOp[] all = values();
|
public static final LogicOp[] all = values();
|
||||||
|
|
||||||
|
public final OpObjLambda2 objFunction2;
|
||||||
public final OpLambda2 function2;
|
public final OpLambda2 function2;
|
||||||
public final OpLambda1 function1;
|
public final OpLambda1 function1;
|
||||||
public final boolean unary;
|
public final boolean unary;
|
||||||
public final String symbol;
|
public final String symbol;
|
||||||
|
|
||||||
LogicOp(String symbol, OpLambda2 function){
|
LogicOp(String symbol, OpLambda2 function){
|
||||||
|
this(symbol, function, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
LogicOp(String symbol, OpLambda2 function, OpObjLambda2 objFunction){
|
||||||
this.symbol = symbol;
|
this.symbol = symbol;
|
||||||
this.function2 = function;
|
this.function2 = function;
|
||||||
this.function1 = null;
|
this.function1 = null;
|
||||||
this.unary = false;
|
this.unary = false;
|
||||||
|
this.objFunction2 = objFunction;
|
||||||
}
|
}
|
||||||
|
|
||||||
LogicOp(String symbol, OpLambda1 function){
|
LogicOp(String symbol, OpLambda1 function){
|
||||||
@ -58,6 +64,7 @@ public enum LogicOp{
|
|||||||
this.function1 = function;
|
this.function1 = function;
|
||||||
this.function2 = null;
|
this.function2 = null;
|
||||||
this.unary = true;
|
this.unary = true;
|
||||||
|
this.objFunction2 = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -65,6 +72,10 @@ public enum LogicOp{
|
|||||||
return symbol;
|
return symbol;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface OpObjLambda2{
|
||||||
|
double get(Object a, Object b);
|
||||||
|
}
|
||||||
|
|
||||||
interface OpLambda2{
|
interface OpLambda2{
|
||||||
double get(double a, double b);
|
double get(double a, double b);
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,12 @@ package mindustry.logic;
|
|||||||
import mindustry.ctype.*;
|
import mindustry.ctype.*;
|
||||||
|
|
||||||
public interface Senseable{
|
public interface Senseable{
|
||||||
|
Object noSensed = new Object();
|
||||||
|
|
||||||
double sense(LAccess sensor);
|
double sense(LAccess sensor);
|
||||||
double sense(Content content);
|
double sense(Content content);
|
||||||
|
|
||||||
|
default Object senseObject(LAccess sensor){
|
||||||
|
return noSensed;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -44,7 +44,7 @@ public class BlockInventoryFragment extends Fragment{
|
|||||||
|
|
||||||
@Remote(called = Loc.server, targets = Loc.both, forward = true)
|
@Remote(called = Loc.server, targets = Loc.both, forward = true)
|
||||||
public static void requestItem(Player player, Building tile, Item item, int amount){
|
public static void requestItem(Player player, Building tile, Item item, int amount){
|
||||||
if(player == null || tile == null || !tile.interactable(player.team())) return;
|
if(player == null || tile == null || !tile.interactable(player.team()) || !player.within(tile, buildingRange)) return;
|
||||||
amount = Math.min(player.unit().maxAccepted(item), amount);
|
amount = Math.min(player.unit().maxAccepted(item), amount);
|
||||||
int fa = amount;
|
int fa = amount;
|
||||||
|
|
||||||
@ -165,7 +165,7 @@ public class BlockInventoryFragment extends Fragment{
|
|||||||
|
|
||||||
container.add(i);
|
container.add(i);
|
||||||
|
|
||||||
Boolp canPick = () -> player.unit().acceptsItem(item) && !state.isPaused();
|
Boolp canPick = () -> player.unit().acceptsItem(item) && !state.isPaused() && player.within(tile, itemTransferRange);
|
||||||
|
|
||||||
HandCursorListener l = new HandCursorListener();
|
HandCursorListener l = new HandCursorListener();
|
||||||
l.setEnabled(canPick);
|
l.setEnabled(canPick);
|
||||||
|
Reference in New Issue
Block a user