Fixed maps not being able to override gamemode-specific settings
This commit is contained in:
@@ -22,7 +22,6 @@ public enum Gamemode{
|
||||
attack(rules -> {
|
||||
rules.enemyCheat = true;
|
||||
rules.unitDrops = true;
|
||||
rules.waves = false;
|
||||
rules.attackMode = true;
|
||||
rules.waves = true;
|
||||
}, map -> map.teams.contains(waveTeam.ordinal())),
|
||||
|
||||
@@ -11,101 +11,7 @@ import io.anuke.mindustry.world.*;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public class JsonIO{
|
||||
private static Json json = new Json(){{
|
||||
setIgnoreUnknownFields(true);
|
||||
setElementType(Rules.class, "spawns", SpawnGroup.class);
|
||||
setElementType(Rules.class, "loadout", ItemStack.class);
|
||||
|
||||
setSerializer(Zone.class, new Serializer<Zone>(){
|
||||
@Override
|
||||
public void write(Json json, Zone object, Class knownType){
|
||||
json.writeValue(object.name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Zone read(Json json, JsonValue jsonData, Class type){
|
||||
return Vars.content.getByName(ContentType.zone, jsonData.asString());
|
||||
}
|
||||
});
|
||||
|
||||
setSerializer(Item.class, new Serializer<Item>(){
|
||||
@Override
|
||||
public void write(Json json, Item object, Class knownType){
|
||||
json.writeValue(object.name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Item read(Json json, JsonValue jsonData, Class type){
|
||||
if(jsonData.asString() == null) return Items.copper;
|
||||
Item i = Vars.content.getByName(ContentType.item, jsonData.asString());
|
||||
return i == null ? Items.copper : i;
|
||||
}
|
||||
});
|
||||
|
||||
//TODO extremely hacky and disgusting
|
||||
for(Block block : Vars.content.blocks()){
|
||||
Class type = block.getClass();
|
||||
if(type.isAnonymousClass()) type = type.getSuperclass();
|
||||
|
||||
setSerializer(type, new Serializer<Block>(){
|
||||
@Override
|
||||
public void write(Json json, Block object, Class knownType){
|
||||
json.writeValue(object.name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Block read(Json json, JsonValue jsonData, Class type){
|
||||
return Vars.content.getByName(ContentType.block, jsonData.asString());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
setSerializer(Block.class, new Serializer<Block>(){
|
||||
@Override
|
||||
public void write(Json json, Block object, Class knownType){
|
||||
json.writeValue(object.name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Block read(Json json, JsonValue jsonData, Class type){
|
||||
return Vars.content.getByName(ContentType.block, jsonData.asString());
|
||||
}
|
||||
});
|
||||
|
||||
setSerializer(TeamData.class, new Serializer<TeamData>(){
|
||||
@Override
|
||||
public void write(Json json, TeamData object, Class knownType){
|
||||
json.writeObjectStart();
|
||||
json.writeValue("brokenBlocks", object.brokenBlocks.toArray());
|
||||
json.writeValue("team", object.team.ordinal());
|
||||
json.writeObjectEnd();
|
||||
}
|
||||
|
||||
@Override
|
||||
public TeamData read(Json json, JsonValue jsonData, Class type){
|
||||
long[] blocks = jsonData.get("brokenBlocks").asLongArray();
|
||||
Team team = Team.all[jsonData.getInt("team", 0)];
|
||||
TeamData out = new TeamData(team, EnumSet.of(new Team[]{}));
|
||||
out.brokenBlocks = new LongQueue(blocks);
|
||||
return out;
|
||||
}
|
||||
});
|
||||
|
||||
setSerializer(ItemStack.class, new Serializer<ItemStack>(){
|
||||
@Override
|
||||
public void write(Json json, ItemStack object, Class knownType){
|
||||
json.writeObjectStart();
|
||||
json.writeValue("item", object.item);
|
||||
json.writeValue("amount", object.amount);
|
||||
json.writeObjectEnd();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack read(Json json, JsonValue jsonData, Class type){
|
||||
return new ItemStack(json.getSerializer(Item.class).read(json, jsonData.get("item"), Item.class), jsonData.getInt("amount"));
|
||||
}
|
||||
});
|
||||
}};
|
||||
private static CustomJson json = new CustomJson();
|
||||
|
||||
public static String write(Object object){
|
||||
return json.toJson(object);
|
||||
@@ -119,7 +25,129 @@ public class JsonIO{
|
||||
return json.fromJson(type, string);
|
||||
}
|
||||
|
||||
public static <T> T read(Class<T> type, T base, String string){
|
||||
return json.fromBaseJson(type, base, string);
|
||||
}
|
||||
|
||||
public static String print(String in){
|
||||
return json.prettyPrint(in);
|
||||
}
|
||||
|
||||
static class CustomJson extends Json{
|
||||
private Object baseObject;
|
||||
|
||||
{
|
||||
setIgnoreUnknownFields(true);
|
||||
setElementType(Rules.class, "spawns", SpawnGroup.class);
|
||||
setElementType(Rules.class, "loadout", ItemStack.class);
|
||||
|
||||
setSerializer(Zone.class, new Serializer<Zone>(){
|
||||
@Override
|
||||
public void write(Json json, Zone object, Class knownType){
|
||||
json.writeValue(object.name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Zone read(Json json, JsonValue jsonData, Class type){
|
||||
return Vars.content.getByName(ContentType.zone, jsonData.asString());
|
||||
}
|
||||
});
|
||||
|
||||
setSerializer(Item.class, new Serializer<Item>(){
|
||||
@Override
|
||||
public void write(Json json, Item object, Class knownType){
|
||||
json.writeValue(object.name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Item read(Json json, JsonValue jsonData, Class type){
|
||||
if(jsonData.asString() == null) return Items.copper;
|
||||
Item i = Vars.content.getByName(ContentType.item, jsonData.asString());
|
||||
return i == null ? Items.copper : i;
|
||||
}
|
||||
});
|
||||
|
||||
//TODO extremely hacky and disgusting
|
||||
for(Block block : Vars.content.blocks()){
|
||||
Class type = block.getClass();
|
||||
if(type.isAnonymousClass()) type = type.getSuperclass();
|
||||
|
||||
setSerializer(type, new Serializer<Block>(){
|
||||
@Override
|
||||
public void write(Json json, Block object, Class knownType){
|
||||
json.writeValue(object.name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Block read(Json json, JsonValue jsonData, Class type){
|
||||
return Vars.content.getByName(ContentType.block, jsonData.asString());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
setSerializer(Block.class, new Serializer<Block>(){
|
||||
@Override
|
||||
public void write(Json json, Block object, Class knownType){
|
||||
json.writeValue(object.name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Block read(Json json, JsonValue jsonData, Class type){
|
||||
return Vars.content.getByName(ContentType.block, jsonData.asString());
|
||||
}
|
||||
});
|
||||
|
||||
setSerializer(TeamData.class, new Serializer<TeamData>(){
|
||||
@Override
|
||||
public void write(Json json, TeamData object, Class knownType){
|
||||
json.writeObjectStart();
|
||||
json.writeValue("brokenBlocks", object.brokenBlocks.toArray());
|
||||
json.writeValue("team", object.team.ordinal());
|
||||
json.writeObjectEnd();
|
||||
}
|
||||
|
||||
@Override
|
||||
public TeamData read(Json json, JsonValue jsonData, Class type){
|
||||
long[] blocks = jsonData.get("brokenBlocks").asLongArray();
|
||||
Team team = Team.all[jsonData.getInt("team", 0)];
|
||||
TeamData out = new TeamData(team, EnumSet.of(new Team[]{}));
|
||||
out.brokenBlocks = new LongQueue(blocks);
|
||||
return out;
|
||||
}
|
||||
});
|
||||
|
||||
setSerializer(ItemStack.class, new Serializer<ItemStack>(){
|
||||
@Override
|
||||
public void write(Json json, ItemStack object, Class knownType){
|
||||
json.writeObjectStart();
|
||||
json.writeValue("item", object.item);
|
||||
json.writeValue("amount", object.amount);
|
||||
json.writeObjectEnd();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack read(Json json, JsonValue jsonData, Class type){
|
||||
return new ItemStack(json.getSerializer(Item.class).read(json, jsonData.get("item"), Item.class), jsonData.getInt("amount"));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T fromJson(Class<T> type, String json){
|
||||
return fromBaseJson(type, null, json);
|
||||
}
|
||||
|
||||
public <T> T fromBaseJson(Class<T> type, T base, String json){
|
||||
this.baseObject = base;
|
||||
return readValue(type, null, new JsonReader().parse(json));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Object newInstance(Class type){
|
||||
if(baseObject == null || baseObject.getClass() != type){
|
||||
return super.newInstance(type);
|
||||
}
|
||||
return baseObject;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -62,10 +62,24 @@ public class Map implements Comparable<Map>{
|
||||
Vars.data.modified();
|
||||
}
|
||||
|
||||
/** Returns the result of applying this map's rules to the specified gamemode.*/
|
||||
public Rules applyRules(Gamemode mode){
|
||||
//mode specific defaults have been applied
|
||||
Rules out = new Rules();
|
||||
mode.apply(out);
|
||||
|
||||
//now apply map-specific overrides
|
||||
return rules(out);
|
||||
}
|
||||
|
||||
/** This creates a new instance of Rules.*/
|
||||
public Rules rules(){
|
||||
return rules(new Rules());
|
||||
}
|
||||
|
||||
public Rules rules(Rules base){
|
||||
try{
|
||||
Rules result = JsonIO.read(Rules.class, tags.get("rules", "{}"));
|
||||
Rules result = JsonIO.read(Rules.class, base, tags.get("rules", "{}"));
|
||||
if(result.spawns.isEmpty()) result.spawns = Vars.defaultWaves.get();
|
||||
return result;
|
||||
}catch(Exception e){
|
||||
|
||||
@@ -1,19 +1,20 @@
|
||||
package io.anuke.mindustry.ui.dialogs;
|
||||
|
||||
import io.anuke.arc.Core;
|
||||
import io.anuke.arc.scene.ui.ScrollPane;
|
||||
import io.anuke.arc.scene.ui.layout.Table;
|
||||
import io.anuke.annotations.Annotations.*;
|
||||
import io.anuke.arc.*;
|
||||
import io.anuke.arc.scene.ui.*;
|
||||
import io.anuke.arc.scene.ui.layout.*;
|
||||
import io.anuke.arc.util.*;
|
||||
import io.anuke.mindustry.game.*;
|
||||
import io.anuke.mindustry.maps.Map;
|
||||
import io.anuke.mindustry.ui.BorderImage;
|
||||
import io.anuke.mindustry.maps.*;
|
||||
import io.anuke.mindustry.ui.*;
|
||||
|
||||
import static io.anuke.mindustry.Vars.*;
|
||||
|
||||
public class MapPlayDialog extends FloatingDialog{
|
||||
CustomRulesDialog dialog = new CustomRulesDialog();
|
||||
Rules rules;
|
||||
Gamemode selectedGamemode = Gamemode.survival;
|
||||
@NonNull Gamemode selectedGamemode = Gamemode.survival;
|
||||
Map lastMap;
|
||||
|
||||
public MapPlayDialog(){
|
||||
@@ -37,10 +38,12 @@ public class MapPlayDialog extends FloatingDialog{
|
||||
//reset to any valid mode after switching to attack (one must exist)
|
||||
if(!selectedGamemode.valid(map)){
|
||||
selectedGamemode = Structs.find(Gamemode.all, m -> m.valid(map));
|
||||
if(selectedGamemode == null){
|
||||
selectedGamemode = Gamemode.survival;
|
||||
}
|
||||
}
|
||||
|
||||
rules = map.rules();
|
||||
rules = selectedGamemode.apply(map.rules());
|
||||
rules = map.applyRules(selectedGamemode);
|
||||
|
||||
Table selmode = new Table();
|
||||
selmode.add("$level.mode").colspan(4);
|
||||
@@ -54,8 +57,7 @@ public class MapPlayDialog extends FloatingDialog{
|
||||
|
||||
modes.addButton(mode.toString(), "toggle", () -> {
|
||||
selectedGamemode = mode;
|
||||
rules = mode.apply(map.rules());
|
||||
Log.info("toggle rules " + rules);
|
||||
rules = map.applyRules(mode);
|
||||
}).update(b -> b.setChecked(selectedGamemode == mode)).size(140f, 54f).disabled(!mode.valid(map));
|
||||
if(i++ % 2 == 1) modes.row();
|
||||
}
|
||||
@@ -64,7 +66,7 @@ public class MapPlayDialog extends FloatingDialog{
|
||||
|
||||
cont.add(selmode);
|
||||
cont.row();
|
||||
cont.addImageTextButton("$customize", "icon-tools-small", iconsizesmall, () -> dialog.show(rules, () -> rules = (selectedGamemode == null ? map.rules() : selectedGamemode.apply(map.rules())))).width(230);
|
||||
cont.addImageTextButton("$customize", "icon-tools-small", iconsizesmall, () -> dialog.show(rules, () -> rules = map.applyRules(selectedGamemode))).width(230);
|
||||
cont.row();
|
||||
cont.add(new BorderImage(map.texture, 3f)).size(mobile && !Core.graphics.isPortrait() ? 150f : 250f).get().setScaling(Scaling.fit);
|
||||
//only maps with survival are valid for high scores
|
||||
|
||||
Reference in New Issue
Block a user