Make custom Env flag reliably possible (#8019)

* Make custom Env flag reliably possible

* screw you

* "compatibility" for mods that don't use add()
This commit is contained in:
GlennFolker 2023-01-08 01:48:28 +07:00 committed by GitHub
parent d7d5ba7510
commit 93f630bb69
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 92 additions and 10 deletions

View File

@ -2,6 +2,7 @@ package mindustry.io;
import arc.graphics.*;
import arc.math.geom.*;
import arc.struct.*;
import arc.util.*;
import arc.util.serialization.*;
import arc.util.serialization.Json.*;
@ -78,6 +79,30 @@ public class JsonIO{
json.setElementType(Rules.class, "spawns", SpawnGroup.class);
json.setElementType(Rules.class, "loadout", ItemStack.class);
json.setSerializer(Rules.class, new Serializer<>(){
@Override
public void write(Json json, Rules object, Class knownType){
json.writeObjectStart();
json.writeFields(object);
json.writeValue("envMapping", Env.idToName, IntMap.class);
json.writeObjectEnd();
}
@Override
public Rules read(Json json, JsonValue jsonData, Class type){
Rules out = new Rules();
json.readFields(out, jsonData);
// Older Rules data doesn't have env mapping.
if(jsonData.has("envMapping")){
IntMap<String> idToName = json.readValue(IntMap.class, jsonData.get("envMapping"));
out.env = Env.remap(out.env, idToName);
}
return out;
}
});
json.setSerializer(Color.class, new Serializer<>(){
@Override
public void write(Json json, Color object, Class knownType){

View File

@ -1,26 +1,83 @@
package mindustry.world.meta;
import arc.struct.*;
import arc.util.*;
/** Environmental flags for different types of locations. */
public class Env{
public static final int
//is on a planet
terrestrial = 1,
terrestrial,
//is in space, no atmosphere
space = 1 << 1,
space,
//is underwater, on a planet
underwater = 1 << 2,
underwater,
//has a spores
spores = 1 << 3,
spores,
//has a scorching env effect
scorching = 1 << 4,
scorching,
//has oil reservoirs
groundOil = 1 << 5,
groundOil,
//has water reservoirs
groundWater = 1 << 6,
groundWater,
//has oxygen in the atmosphere
oxygen = 1 << 7,
oxygen,
//all attributes combined, only used for bitmasking purposes
any = 0xffffffff,
//no attributes (0)
none = 0;
//do NOT modify directly!
public static final ObjectIntMap<String> nameToId;
public static final IntMap<String> idToName;
static{
//last time i didn't use a static initializer i got a null pointer.
//i can probably just move the fields around, but i don't trust java enough for that
nameToId = new ObjectIntMap<>();
idToName = new IntMap<>();
terrestrial = add("terrestrial");
space = add("space");
underwater = add("underwater");
spores = add("spores");
scorching = add("scorching");
groundOil = add("groundOil");
groundWater = add("groundWater");
oxygen = add("oxygen");
}
public static int add(String key){
if(nameToId.containsKey(key)) throw new IllegalArgumentException("'" + key + "' env already exists.");
if(nameToId.size >= 32) throw new IllegalStateException("Max env count 32 exceeded.");
int id = 1 << nameToId.size;
nameToId.put(key, id);
idToName.put(id, key);
return id;
}
public static int remap(int mask, IntMap<String> idToName){
int out = 0;
for(int i = 0; i < 32; i++){
int key = 1 << i;
if((mask & key) == key){
String name = idToName.get(key);
if(name == null){
//if it's unmapped it's probably just some mods using constant value
out |= key;
continue;
}
int id = nameToId.get(name, -1);
if(id == -1){
Log.warn("Ignoring '@' env key.", name);
}else{
out |= id;
}
}
}
return out;
}
}

View File

@ -190,7 +190,7 @@ public class ApplicationTests{
@Test
void writeRules(){
ByteBuffer buffer = ByteBuffer.allocate(500);
ByteBuffer buffer = ByteBuffer.allocate(1000);
Rules rules = new Rules();
rules.attackMode = true;
@ -981,4 +981,4 @@ public class ApplicationTests{
tile.build.handleStack(item, 1, unit);
assertEquals(capacity, tile.build.items.get(item));
}
}
}