Fixed maps not being able to override gamemode-specific settings

This commit is contained in:
Anuken
2019-08-10 11:43:28 -04:00
parent 16f6b51857
commit 4ef60af4a8
25 changed files with 153 additions and 110 deletions
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -22,7 +22,6 @@ public enum Gamemode{
attack(rules -> { attack(rules -> {
rules.enemyCheat = true; rules.enemyCheat = true;
rules.unitDrops = true; rules.unitDrops = true;
rules.waves = false;
rules.attackMode = true; rules.attackMode = true;
rules.waves = true; rules.waves = true;
}, map -> map.teams.contains(waveTeam.ordinal())), }, map -> map.teams.contains(waveTeam.ordinal())),
+39 -11
View File
@@ -11,7 +11,32 @@ import io.anuke.mindustry.world.*;
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public class JsonIO{ public class JsonIO{
private static Json json = new Json(){{ private static CustomJson json = new CustomJson();
public static String write(Object object){
return json.toJson(object);
}
public static <T> T copy(T object){
return read((Class<T>)object.getClass(), write(object));
}
public static <T> T read(Class<T> type, String string){
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); setIgnoreUnknownFields(true);
setElementType(Rules.class, "spawns", SpawnGroup.class); setElementType(Rules.class, "spawns", SpawnGroup.class);
setElementType(Rules.class, "loadout", ItemStack.class); setElementType(Rules.class, "loadout", ItemStack.class);
@@ -105,21 +130,24 @@ public class JsonIO{
return new ItemStack(json.getSerializer(Item.class).read(json, jsonData.get("item"), Item.class), jsonData.getInt("amount")); return new ItemStack(json.getSerializer(Item.class).read(json, jsonData.get("item"), Item.class), jsonData.getInt("amount"));
} }
}); });
}};
public static String write(Object object){
return json.toJson(object);
} }
public static <T> T copy(T object){ @Override
return read((Class<T>)object.getClass(), write(object)); public <T> T fromJson(Class<T> type, String json){
return fromBaseJson(type, null, json);
} }
public static <T> T read(Class<T> type, String string){ public <T> T fromBaseJson(Class<T> type, T base, String json){
return json.fromJson(type, string); this.baseObject = base;
return readValue(type, null, new JsonReader().parse(json));
} }
public static String print(String in){ @Override
return json.prettyPrint(in); protected Object newInstance(Class type){
if(baseObject == null || baseObject.getClass() != type){
return super.newInstance(type);
}
return baseObject;
}
} }
} }
+15 -1
View File
@@ -62,10 +62,24 @@ public class Map implements Comparable<Map>{
Vars.data.modified(); 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.*/ /** This creates a new instance of Rules.*/
public Rules rules(){ public Rules rules(){
return rules(new Rules());
}
public Rules rules(Rules base){
try{ 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(); if(result.spawns.isEmpty()) result.spawns = Vars.defaultWaves.get();
return result; return result;
}catch(Exception e){ }catch(Exception e){
@@ -1,19 +1,20 @@
package io.anuke.mindustry.ui.dialogs; package io.anuke.mindustry.ui.dialogs;
import io.anuke.arc.Core; import io.anuke.annotations.Annotations.*;
import io.anuke.arc.scene.ui.ScrollPane; import io.anuke.arc.*;
import io.anuke.arc.scene.ui.layout.Table; import io.anuke.arc.scene.ui.*;
import io.anuke.arc.scene.ui.layout.*;
import io.anuke.arc.util.*; import io.anuke.arc.util.*;
import io.anuke.mindustry.game.*; import io.anuke.mindustry.game.*;
import io.anuke.mindustry.maps.Map; import io.anuke.mindustry.maps.*;
import io.anuke.mindustry.ui.BorderImage; import io.anuke.mindustry.ui.*;
import static io.anuke.mindustry.Vars.*; import static io.anuke.mindustry.Vars.*;
public class MapPlayDialog extends FloatingDialog{ public class MapPlayDialog extends FloatingDialog{
CustomRulesDialog dialog = new CustomRulesDialog(); CustomRulesDialog dialog = new CustomRulesDialog();
Rules rules; Rules rules;
Gamemode selectedGamemode = Gamemode.survival; @NonNull Gamemode selectedGamemode = Gamemode.survival;
Map lastMap; Map lastMap;
public MapPlayDialog(){ public MapPlayDialog(){
@@ -37,10 +38,12 @@ public class MapPlayDialog extends FloatingDialog{
//reset to any valid mode after switching to attack (one must exist) //reset to any valid mode after switching to attack (one must exist)
if(!selectedGamemode.valid(map)){ if(!selectedGamemode.valid(map)){
selectedGamemode = Structs.find(Gamemode.all, m -> m.valid(map)); selectedGamemode = Structs.find(Gamemode.all, m -> m.valid(map));
if(selectedGamemode == null){
selectedGamemode = Gamemode.survival;
}
} }
rules = map.rules(); rules = map.applyRules(selectedGamemode);
rules = selectedGamemode.apply(map.rules());
Table selmode = new Table(); Table selmode = new Table();
selmode.add("$level.mode").colspan(4); selmode.add("$level.mode").colspan(4);
@@ -54,8 +57,7 @@ public class MapPlayDialog extends FloatingDialog{
modes.addButton(mode.toString(), "toggle", () -> { modes.addButton(mode.toString(), "toggle", () -> {
selectedGamemode = mode; selectedGamemode = mode;
rules = mode.apply(map.rules()); rules = map.applyRules(mode);
Log.info("toggle rules " + rules);
}).update(b -> b.setChecked(selectedGamemode == mode)).size(140f, 54f).disabled(!mode.valid(map)); }).update(b -> b.setChecked(selectedGamemode == mode)).size(140f, 54f).disabled(!mode.valid(map));
if(i++ % 2 == 1) modes.row(); if(i++ % 2 == 1) modes.row();
} }
@@ -64,7 +66,7 @@ public class MapPlayDialog extends FloatingDialog{
cont.add(selmode); cont.add(selmode);
cont.row(); 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.row();
cont.add(new BorderImage(map.texture, 3f)).size(mobile && !Core.graphics.isPortrait() ? 150f : 250f).get().setScaling(Scaling.fit); 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 //only maps with survival are valid for high scores
@@ -239,7 +239,7 @@ public class ServerControl implements ApplicationListener{
lastMode = preset; lastMode = preset;
try{ try{
world.loadMap(result); world.loadMap(result);
state.rules = preset.apply(result.rules()); state.rules = result.applyRules(preset);
logic.play(); logic.play();
info("Map loaded."); info("Map loaded.");
@@ -706,7 +706,7 @@ public class ServerControl implements ApplicationListener{
Call.onWorldDataBegin(); Call.onWorldDataBegin();
run.run(); run.run();
logic.play(); logic.play();
state.rules = lastMode.apply(world.getMap().rules()); state.rules = world.getMap().applyRules(lastMode);
for(Player p : players){ for(Player p : players){
p.reset(); p.reset();
if(state.rules.pvp){ if(state.rules.pvp){