Files
Mindustry/core/src/mindustry/logic/GlobalVars.java

209 lines
7.1 KiB
Java
Raw Normal View History

package mindustry.logic;
import arc.*;
import arc.files.*;
2023-08-02 22:15:44 -04:00
import arc.graphics.*;
import arc.math.*;
import arc.struct.*;
import arc.util.*;
import mindustry.*;
import mindustry.content.*;
import mindustry.ctype.*;
2022-02-08 13:20:55 -05:00
import mindustry.game.*;
import mindustry.logic.LExecutor.*;
import mindustry.type.*;
import mindustry.world.*;
import mindustry.world.blocks.legacy.*;
import java.io.*;
2022-02-08 12:18:48 -05:00
import static mindustry.Vars.*;
2022-05-08 17:07:06 -04:00
/** Stores global logic variables for logic processors. */
public class GlobalVars{
2022-04-10 10:23:35 -04:00
public static final int ctrlProcessor = 1, ctrlPlayer = 2, ctrlCommand = 3;
public static final ContentType[] lookableContent = {ContentType.block, ContentType.unit, ContentType.item, ContentType.liquid};
/** Global random state. */
public static final Rand rand = new Rand();
2021-03-05 14:00:53 -05:00
2022-02-08 12:18:48 -05:00
//non-constants that depend on state
2023-09-28 01:04:03 -04:00
private static int varTime, varTick, varSecond, varMinute, varWave, varWaveTime, varServer, varClient;
2022-02-08 12:18:48 -05:00
private ObjectIntMap<String> namesToIds = new ObjectIntMap<>();
private Seq<Var> vars = new Seq<>(Var.class);
private UnlockableContent[][] logicIdToContent;
private int[][] contentIdToLogicId;
public void init(){
put("the end", null);
//add default constants
put("false", 0);
put("true", 1);
put("null", null);
2023-04-06 10:46:52 -04:00
//math
put("@pi", Mathf.PI);
put("π", Mathf.PI); //for the "cool" kids
put("@e", Mathf.E);
put("@degToRad", Mathf.degRad);
put("@radToDeg", Mathf.radDeg);
2023-04-06 10:46:52 -04:00
2022-02-08 12:18:48 -05:00
//time
varTime = put("@time", 0);
varTick = put("@tick", 0);
2022-03-13 21:39:35 -04:00
varSecond = put("@second", 0);
varMinute = put("@minute", 0);
2022-02-08 12:18:48 -05:00
varWave = put("@waveNumber", 0);
varWaveTime = put("@waveTime", 0);
varServer = put("@server", 0);
2023-09-28 08:52:08 -04:00
varClient = put("@client", 0);
2021-02-21 12:28:00 -05:00
//special enums
2021-03-05 14:00:53 -05:00
put("@ctrlProcessor", ctrlProcessor);
put("@ctrlPlayer", ctrlPlayer);
2022-04-10 10:23:35 -04:00
put("@ctrlCommand", ctrlCommand);
2021-02-21 12:28:00 -05:00
//store base content
2022-02-08 13:20:55 -05:00
for(Team team : Team.baseTeams){
put("@" + team.name, team);
}
for(Item item : Vars.content.items()){
put("@" + item.name, item);
}
for(Liquid liquid : Vars.content.liquids()){
put("@" + liquid.name, liquid);
}
for(Block block : Vars.content.blocks()){
//only register blocks that have no item equivalent (this skips sand)
if(content.item(block.name) == null & !(block instanceof LegacyBlock)){
put("@" + block.name, block);
}
}
2023-08-02 22:15:44 -04:00
for(var entry : Colors.getColors().entries()){
//ignore uppercase variants, they are duplicates
if(Character.isUpperCase(entry.key.charAt(0))) continue;
put("@color" + Strings.capitalize(entry.key), entry.value.toDoubleBits());
}
//used as a special value for any environmental solid block
put("@solid", Blocks.stoneWall);
for(UnitType type : Vars.content.units()){
put("@" + type.name, type);
}
//store sensor constants
for(LAccess sensor : LAccess.all){
put("@" + sensor.name(), sensor);
}
logicIdToContent = new UnlockableContent[ContentType.all.length][];
contentIdToLogicId = new int[ContentType.all.length][];
Fi ids = Core.files.internal("logicids.dat");
if(ids.exists()){
//read logic ID mapping data (generated in ImagePacker)
try(DataInputStream in = new DataInputStream(ids.readByteStream())){
for(ContentType ctype : lookableContent){
short amount = in.readShort();
logicIdToContent[ctype.ordinal()] = new UnlockableContent[amount];
contentIdToLogicId[ctype.ordinal()] = new int[Vars.content.getBy(ctype).size];
//store count constants
put("@" + ctype.name() + "Count", amount);
for(int i = 0; i < amount; i++){
String name = in.readUTF();
UnlockableContent fetched = Vars.content.getByName(ctype, name);
if(fetched != null){
logicIdToContent[ctype.ordinal()][i] = fetched;
contentIdToLogicId[ctype.ordinal()][fetched.id] = i;
}
}
}
}catch(IOException e){
//don't crash?
Log.err("Error reading logic ID mapping", e);
}
}
}
2022-02-08 12:18:48 -05:00
/** Updates global time and other state variables. */
public void update(){
//set up time; note that @time is now only updated once every invocation and directly based off of @tick.
//having time be based off of user system time was a very bad idea.
vars.items[varTime].numval = state.tick / 60.0 * 1000.0;
vars.items[varTick].numval = state.tick;
2022-03-13 21:39:35 -04:00
//shorthands for seconds/minutes spent in save
vars.items[varSecond].numval = state.tick / 60f;
vars.items[varMinute].numval = state.tick / 60f / 60f;
2022-02-08 12:18:48 -05:00
//wave state
vars.items[varWave].numval = state.wave;
vars.items[varWaveTime].numval = state.wavetime / 60f;
//network
vars.items[varServer].numval = (net.server() || !net.active()) ? 1 : 0;
2023-09-28 01:04:03 -04:00
vars.items[varServer].numval = net.client() ? 1 : 0;
2022-02-08 12:18:48 -05:00
}
/** @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()];
return arr != null && id >= 0 && id < arr.length ? arr[id] : null;
}
/** @return the integer logic ID of content, or -1 if invalid. */
public int lookupLogicId(UnlockableContent content){
var arr = contentIdToLogicId[content.getContentType().ordinal()];
return arr != null && content.id >= 0 && content.id < arr.length ? arr[content.id] : -1;
}
/** @return a constant ID > 0 if there is a constant with this name, otherwise -1. */
public int get(String name){
return namesToIds.get(name, -1);
}
/** @return a constant variable by ID. ID is not bound checked and must be positive. */
public Var get(int id){
return vars.items[id];
}
2022-02-08 12:18:48 -05:00
/** Sets a global variable by an ID returned from put(). */
public void set(int id, double value){
get(id).numval = value;
}
/** Adds a constant value by name. */
2022-02-08 12:18:48 -05:00
public int put(String name, Object value){
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);
return existingIdx;
}
Var var = new Var(name);
var.constant = true;
if(value instanceof Number num){
var.numval = num.doubleValue();
}else{
var.isobj = true;
var.objval = value;
}
int index = vars.size;
namesToIds.put(name, index);
vars.add(var);
2022-02-08 12:18:48 -05:00
return index;
}
}