Fixed maps not being able to override gamemode-specific settings
This commit is contained in:
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())),
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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){
|
||||
|
||||
Reference in New Issue
Block a user