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 -> {
rules.enemyCheat = true;
rules.unitDrops = true;
rules.waves = false;
rules.attackMode = true;
rules.waves = true;
}, map -> map.teams.contains(waveTeam.ordinal())),
+39 -11
View File
@@ -11,7 +11,32 @@ import io.anuke.mindustry.world.*;
@SuppressWarnings("unchecked")
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);
setElementType(Rules.class, "spawns", SpawnGroup.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"));
}
});
}};
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));
@Override
public <T> T fromJson(Class<T> type, String json){
return fromBaseJson(type, null, json);
}
public static <T> T read(Class<T> type, String string){
return json.fromJson(type, string);
public <T> T fromBaseJson(Class<T> type, T base, String json){
this.baseObject = base;
return readValue(type, null, new JsonReader().parse(json));
}
public static String print(String in){
return json.prettyPrint(in);
@Override
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();
}
/** 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
@@ -239,7 +239,7 @@ public class ServerControl implements ApplicationListener{
lastMode = preset;
try{
world.loadMap(result);
state.rules = preset.apply(result.rules());
state.rules = result.applyRules(preset);
logic.play();
info("Map loaded.");
@@ -706,7 +706,7 @@ public class ServerControl implements ApplicationListener{
Call.onWorldDataBegin();
run.run();
logic.play();
state.rules = lastMode.apply(world.getMap().rules());
state.rules = world.getMap().applyRules(lastMode);
for(Player p : players){
p.reset();
if(state.rules.pvp){