mirror of
https://github.com/Anuken/Mindustry.git
synced 2026-01-26 14:32:06 -08:00
Processor global variable dialog
This commit is contained in:
parent
3d1067aac0
commit
2fd92b8c80
6 changed files with 201 additions and 29 deletions
|
|
@ -501,6 +501,7 @@ editor.default = [lightgray]<Default>
|
|||
details = Details...
|
||||
edit = Edit
|
||||
variables = Vars
|
||||
logic.globals = Built-in Variables
|
||||
editor.name = Name:
|
||||
editor.spawn = Spawn Unit
|
||||
editor.removeunit = Remove Unit
|
||||
|
|
@ -2330,6 +2331,49 @@ lst.makemarker = Create a new logic marker in the world.\nAn ID to identify this
|
|||
lst.setmarker = Set a property for a marker.\nThe ID used must be the same as in the Make Marker instruction.\n[accent]null []values are ignored.
|
||||
lst.localeprint = Add map locale property value to the text buffer.\nTo set map locale bundles in map editor, check [accent]Map Info > Locale Bundles[].\nIf client is a mobile device, tries to print a property ending in ".mobile" first.
|
||||
|
||||
lglobal.false = 0
|
||||
lglobal.true = 1
|
||||
lglobal.null = null
|
||||
lglobal.@pi = The mathematical constant pi (3.141...)
|
||||
lglobal.@e = The mathematical constant e (2.718...)
|
||||
lglobal.@degToRad = Multiply by this number to convert degrees to radians
|
||||
lglobal.@radToDeg = Multiply by this number to convert radians to degrees
|
||||
|
||||
lglobal.@time = Playtime of current save, in milliseconds
|
||||
lglobal.@tick = Playtime of current save, in ticks (1 second = 60 ticks)
|
||||
lglobal.@second = Playtime of current save, in seconds
|
||||
lglobal.@minute = Playtime of current save, in minutes
|
||||
lglobal.@waveNumber = Current wave number, if waves are enabled
|
||||
lglobal.@waveTime = Countdown timer for waves, in seconds
|
||||
lglobal.@mapw = Map width in tiles
|
||||
lglobal.@maph = Map height in tiles
|
||||
|
||||
lglobal.sectionMap = Map
|
||||
lglobal.sectionGeneral = General
|
||||
lglobal.sectionNetwork = Network/Clientside [World Processor Only]
|
||||
lglobal.sectionProcessor = Processor
|
||||
lglobal.sectionLookup = Lookup
|
||||
|
||||
lglobal.@this = The logic block executing the code
|
||||
lglobal.@thisx = X coordinate of block executing the code
|
||||
lglobal.@thisy = Y coordinate of block executing the code
|
||||
lglobal.@links = Total number of blocks linked to this processors
|
||||
lglobal.@ipt = Execution speed of the processor in instructions per tick (60 ticks = 1 second)
|
||||
|
||||
lglobal.@unitCount = Total number of types of unit content in the game; used with the lookup instruction
|
||||
lglobal.@blockCount = Total number of types of block content in the game; used with the lookup instruction
|
||||
lglobal.@itemCount = Total number of types of item content in the game; used with the lookup instruction
|
||||
lglobal.@liquidCount = Total number of types of liquid content in the game; used with the lookup instruction
|
||||
|
||||
lglobal.@server = True if the code is running on a server or in singleplayer, false otherwise
|
||||
lglobal.@client = True if the code is running on a client connected to a server
|
||||
|
||||
lglobal.@clientLocale = Locale of the client running the code. For example: en_US
|
||||
lglobal.@clientUnit = Unit of client running the code
|
||||
lglobal.@clientName = Player name of client running the code
|
||||
lglobal.@clientTeam = Team ID of client running the code
|
||||
lglobal.@clientMobile = True is the client running the code is on mobile, false otherwise
|
||||
|
||||
logic.nounitbuild = [red]Unit building logic is not allowed here.
|
||||
|
||||
lenum.type = Type of building/unit.\ne.g. for any router, this will return [accent]@router[].\nNot a string.
|
||||
|
|
|
|||
|
|
@ -27,45 +27,63 @@ public class GlobalVars{
|
|||
public static final Rand rand = new Rand();
|
||||
|
||||
//non-constants that depend on state
|
||||
private static int varTime, varTick, varSecond, varMinute, varWave, varWaveTime, varServer, varClient, varClientLocale, varClientUnit, varClientName, varClientTeam, varClientMobile;
|
||||
private static int varTime, varTick, varSecond, varMinute, varWave, varWaveTime, varMapW, varMapH, varServer, varClient, varClientLocale, varClientUnit, varClientName, varClientTeam, varClientMobile;
|
||||
|
||||
private ObjectIntMap<String> namesToIds = new ObjectIntMap<>();
|
||||
private Seq<Var> vars = new Seq<>(Var.class);
|
||||
private Seq<VarEntry> varEntries = new Seq<>();
|
||||
private IntSet privilegedIds = new IntSet();
|
||||
private UnlockableContent[][] logicIdToContent;
|
||||
private int[][] contentIdToLogicId;
|
||||
|
||||
public void init(){
|
||||
put("the end", null);
|
||||
putEntryOnly("sectionProcessor");
|
||||
|
||||
putEntryOnly("@this");
|
||||
putEntryOnly("@thisx");
|
||||
putEntryOnly("@thisy");
|
||||
putEntryOnly("@links");
|
||||
putEntryOnly("@ipt");
|
||||
|
||||
putEntryOnly("sectionGeneral");
|
||||
|
||||
put("the end", null, false, true);
|
||||
//add default constants
|
||||
put("false", 0);
|
||||
put("true", 1);
|
||||
put("null", null);
|
||||
putEntry("false", 0);
|
||||
putEntry("true", 1);
|
||||
put("null", null, false, true);
|
||||
|
||||
//math
|
||||
put("@pi", Mathf.PI);
|
||||
put("π", Mathf.PI); //for the "cool" kids
|
||||
put("@e", Mathf.E);
|
||||
put("@degToRad", Mathf.degRad);
|
||||
put("@radToDeg", Mathf.radDeg);
|
||||
putEntry("@pi", Mathf.PI);
|
||||
put("π", Mathf.PI, false, true); //for the "cool" kids
|
||||
putEntry("@e", Mathf.E);
|
||||
putEntry("@degToRad", Mathf.degRad);
|
||||
putEntry("@radToDeg", Mathf.radDeg);
|
||||
|
||||
putEntryOnly("sectionMap");
|
||||
|
||||
//time
|
||||
varTime = put("@time", 0);
|
||||
varTick = put("@tick", 0);
|
||||
varSecond = put("@second", 0);
|
||||
varMinute = put("@minute", 0);
|
||||
varWave = put("@waveNumber", 0);
|
||||
varWaveTime = put("@waveTime", 0);
|
||||
varTime = putEntry("@time", 0);
|
||||
varTick = putEntry("@tick", 0);
|
||||
varSecond = putEntry("@second", 0);
|
||||
varMinute = putEntry("@minute", 0);
|
||||
varWave = putEntry("@waveNumber", 0);
|
||||
varWaveTime = putEntry("@waveTime", 0);
|
||||
|
||||
varServer = put("@server", 0, true);
|
||||
varClient = put("@client", 0, true);
|
||||
varMapW = putEntry("@mapw", 0);
|
||||
varMapH = putEntry("@maph", 0);
|
||||
|
||||
putEntryOnly("sectionNetwork");
|
||||
|
||||
varServer = putEntry("@server", 0, true);
|
||||
varClient = putEntry("@client", 0, true);
|
||||
|
||||
//privileged desynced client variables
|
||||
varClientLocale = put("@clientLocale", null, true);
|
||||
varClientUnit = put("@clientUnit", null, true);
|
||||
varClientName = put("@clientName", null, true);
|
||||
varClientTeam = put("@clientTeam", 0, true);
|
||||
varClientMobile = put("@clientMobile", 0, true);
|
||||
varClientLocale = putEntry("@clientLocale", null, true);
|
||||
varClientUnit = putEntry("@clientUnit", null, true);
|
||||
varClientName = putEntry("@clientName", null, true);
|
||||
varClientTeam = putEntry("@clientTeam", 0, true);
|
||||
varClientMobile = putEntry("@clientMobile", 0, true);
|
||||
|
||||
//special enums
|
||||
put("@ctrlProcessor", ctrlProcessor);
|
||||
|
|
@ -115,6 +133,8 @@ public class GlobalVars{
|
|||
logicIdToContent = new UnlockableContent[ContentType.all.length][];
|
||||
contentIdToLogicId = new int[ContentType.all.length][];
|
||||
|
||||
putEntryOnly("sectionLookup");
|
||||
|
||||
Fi ids = Core.files.internal("logicids.dat");
|
||||
if(ids.exists()){
|
||||
//read logic ID mapping data (generated in ImagePacker)
|
||||
|
|
@ -125,7 +145,7 @@ public class GlobalVars{
|
|||
contentIdToLogicId[ctype.ordinal()] = new int[Vars.content.getBy(ctype).size];
|
||||
|
||||
//store count constants
|
||||
put("@" + ctype.name() + "Count", amount);
|
||||
putEntry("@" + ctype.name() + "Count", amount);
|
||||
|
||||
for(int i = 0; i < amount; i++){
|
||||
String name = in.readUTF();
|
||||
|
|
@ -159,6 +179,9 @@ public class GlobalVars{
|
|||
vars.items[varWave].numval = state.wave;
|
||||
vars.items[varWaveTime].numval = state.wavetime / 60f;
|
||||
|
||||
vars.items[varMapW].numval = world.width();
|
||||
vars.items[varMapH].numval = world.height();
|
||||
|
||||
//network
|
||||
vars.items[varServer].numval = (net.server() || !net.active()) ? 1 : 0;
|
||||
vars.items[varClient].numval = net.client() ? 1 : 0;
|
||||
|
|
@ -173,6 +196,10 @@ public class GlobalVars{
|
|||
}
|
||||
}
|
||||
|
||||
public Seq<VarEntry> getEntries(){
|
||||
return varEntries;
|
||||
}
|
||||
|
||||
/** @return a piece of content based on its logic ID. This is not equivalent to content ID. */
|
||||
public @Nullable Content lookupContent(ContentType type, int id){
|
||||
var arr = logicIdToContent[type.ordinal()];
|
||||
|
|
@ -209,6 +236,11 @@ public class GlobalVars{
|
|||
|
||||
/** Adds a constant value by name. */
|
||||
public int put(String name, Object value, boolean privileged){
|
||||
return put(name, value, privileged, true);
|
||||
}
|
||||
|
||||
/** Adds a constant value by name. */
|
||||
public int put(String name, Object value, boolean privileged, boolean hidden){
|
||||
int existingIdx = namesToIds.get(name, -1);
|
||||
if(existingIdx != -1){ //don't overwrite existing vars (see #6910)
|
||||
Log.debug("Failed to add global logic variable '@', as it already exists.", name);
|
||||
|
|
@ -228,10 +260,44 @@ public class GlobalVars{
|
|||
namesToIds.put(name, index);
|
||||
if(privileged) privilegedIds.add(index);
|
||||
vars.add(var);
|
||||
|
||||
if(!hidden){
|
||||
varEntries.add(new VarEntry(index, name, "", "", privileged));
|
||||
}
|
||||
return index;
|
||||
}
|
||||
|
||||
public int put(String name, Object value){
|
||||
return put(name, value, false);
|
||||
}
|
||||
|
||||
public int putEntry(String name, Object value){
|
||||
return put(name, value, false, false);
|
||||
}
|
||||
|
||||
public int putEntry(String name, Object value, boolean privileged){
|
||||
return put(name, value, privileged, false);
|
||||
}
|
||||
|
||||
public void putEntryOnly(String name){
|
||||
varEntries.add(new VarEntry(0, name, "", "", false));
|
||||
}
|
||||
|
||||
/** An entry that describes a variable for documentation purposes. This is *only* used inside UI for global variables. */
|
||||
public static class VarEntry{
|
||||
public int id;
|
||||
public String name, description, icon;
|
||||
public boolean privileged;
|
||||
|
||||
public VarEntry(int id, String name, String description, String icon, boolean privileged){
|
||||
this.id = id;
|
||||
this.name = name;
|
||||
this.description = description;
|
||||
this.icon = icon;
|
||||
this.privileged = privileged;
|
||||
}
|
||||
|
||||
public VarEntry(){
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
61
core/src/mindustry/logic/GlobalVarsDialog.java
Normal file
61
core/src/mindustry/logic/GlobalVarsDialog.java
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
package mindustry.logic;
|
||||
|
||||
import arc.*;
|
||||
import arc.graphics.*;
|
||||
import arc.scene.ui.*;
|
||||
import arc.scene.ui.layout.*;
|
||||
import arc.util.*;
|
||||
import mindustry.*;
|
||||
import mindustry.gen.*;
|
||||
import mindustry.graphics.*;
|
||||
import mindustry.ui.*;
|
||||
import mindustry.ui.dialogs.*;
|
||||
|
||||
public class GlobalVarsDialog extends BaseDialog{
|
||||
|
||||
public GlobalVarsDialog(){
|
||||
super("@logic.globals");
|
||||
|
||||
addCloseButton();
|
||||
shown(this::setup);
|
||||
onResize(this::setup);
|
||||
}
|
||||
|
||||
void setup(){
|
||||
float prefWidth = Math.min(Core.graphics.getWidth() * 0.9f / Scl.scl(1f) - 220f, 600f);
|
||||
cont.clearChildren();
|
||||
|
||||
cont.pane(t -> {
|
||||
t.margin(10f).marginRight(16f);
|
||||
t.defaults().fillX().fillY();
|
||||
for(var entry : Vars.logicVars.getEntries()){
|
||||
|
||||
if(entry.name.startsWith("section")){
|
||||
Color color = Pal.accent;
|
||||
t.add("@lglobal." + entry.name).fillX().center().labelAlign(Align.center).colspan(4).color(color).padTop(4f).padBottom(2f).row();
|
||||
t.image(Tex.whiteui).height(4f).color(color).colspan(4).padBottom(8f).row();
|
||||
}else{
|
||||
Color varColor = Pal.gray;
|
||||
float stub = 8f, mul = 0.5f, pad = 4;
|
||||
|
||||
String desc = entry.description;
|
||||
if(desc == null || desc.isEmpty()){
|
||||
desc = Core.bundle.get("lglobal." + entry.name, "");
|
||||
}
|
||||
|
||||
String fdesc = desc;
|
||||
|
||||
t.add(new Image(Tex.whiteui, varColor.cpy().mul(mul))).width(stub);
|
||||
t.stack(new Image(Tex.whiteui, varColor), new Label(" " + entry.name + " ", Styles.outlineLabel)).padRight(pad);
|
||||
|
||||
t.add(new Image(Tex.whiteui, Pal.gray.cpy().mul(mul))).width(stub);
|
||||
t.table(Tex.pane, out -> out.add(fdesc).style(Styles.outlineLabel).width(prefWidth).padLeft(2).padRight(2).wrap()).padRight(pad);
|
||||
|
||||
t.row();
|
||||
|
||||
t.add().fillX().colspan(4).height(4).row();
|
||||
}
|
||||
}
|
||||
}).grow();
|
||||
}
|
||||
}
|
||||
|
|
@ -26,6 +26,7 @@ public class LogicDialog extends BaseDialog{
|
|||
Cons<String> consumer = s -> {};
|
||||
boolean privileged;
|
||||
@Nullable LExecutor executor;
|
||||
GlobalVarsDialog globalsDialog = new GlobalVarsDialog();
|
||||
|
||||
public LogicDialog(){
|
||||
super("logic");
|
||||
|
|
@ -51,7 +52,7 @@ public class LogicDialog extends BaseDialog{
|
|||
add(buttons).growX().name("canvas");
|
||||
}
|
||||
|
||||
private Color typeColor(Var s, Color color){
|
||||
public static Color typeColor(Var s, Color color){
|
||||
return color.set(
|
||||
!s.isobj ? Pal.place :
|
||||
s.objval == null ? Color.darkGray :
|
||||
|
|
@ -65,7 +66,7 @@ public class LogicDialog extends BaseDialog{
|
|||
);
|
||||
}
|
||||
|
||||
private String typeName(Var s){
|
||||
public static String typeName(Var s){
|
||||
return
|
||||
!s.isobj ? "number" :
|
||||
s.objval == null ? "null" :
|
||||
|
|
@ -178,6 +179,8 @@ public class LogicDialog extends BaseDialog{
|
|||
});
|
||||
|
||||
dialog.addCloseButton();
|
||||
dialog.buttons.button("@logic.globals", Icon.list, () -> globalsDialog.show()).size(210f, 64f);
|
||||
|
||||
dialog.show();
|
||||
}).name("variables").disabled(b -> executor == null || executor.vars.length == 0);
|
||||
|
||||
|
|
|
|||
|
|
@ -354,8 +354,6 @@ public class LogicBlock extends Block{
|
|||
}
|
||||
}
|
||||
|
||||
asm.putConst("@mapw", world.width());
|
||||
asm.putConst("@maph", world.height());
|
||||
asm.putConst("@links", executor.links.length);
|
||||
asm.putConst("@ipt", instructionsPerTick);
|
||||
|
||||
|
|
|
|||
|
|
@ -25,4 +25,4 @@ org.gradle.caching=true
|
|||
#used for slow jitpack builds; TODO see if this actually works
|
||||
org.gradle.internal.http.socketTimeout=100000
|
||||
org.gradle.internal.http.connectionTimeout=100000
|
||||
archash=f3b941e548
|
||||
archash=a2acd2ee5f
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue