Data patcher unit controller support / Warnings for invalid sounds in JSON/DP
This commit is contained in:
@@ -7,6 +7,7 @@ import arc.assets.loaders.SoundLoader.*;
|
|||||||
import arc.audio.*;
|
import arc.audio.*;
|
||||||
import arc.files.*;
|
import arc.files.*;
|
||||||
import arc.struct.*;
|
import arc.struct.*;
|
||||||
|
import arc.util.*;
|
||||||
import mindustry.*;
|
import mindustry.*;
|
||||||
import mindustry.gen.*;
|
import mindustry.gen.*;
|
||||||
|
|
||||||
@@ -57,9 +58,11 @@ public class FileTree implements FileHandleResolver{
|
|||||||
|
|
||||||
return loadedSounds.get(soundName, () -> {
|
return loadedSounds.get(soundName, () -> {
|
||||||
String name = "sounds/" + soundName;
|
String name = "sounds/" + soundName;
|
||||||
String path = Vars.tree.get(name + ".ogg").exists() ? name + ".ogg" : name + ".mp3";
|
String path = getAudioPath(name);
|
||||||
|
|
||||||
var sound = new Sound();
|
var sound = new Sound();
|
||||||
|
|
||||||
|
if(path == null) return sound;
|
||||||
var desc = Core.assets.load(path, Sound.class, new SoundParameter(sound));
|
var desc = Core.assets.load(path, Sound.class, new SoundParameter(sound));
|
||||||
desc.errored = Throwable::printStackTrace;
|
desc.errored = Throwable::printStackTrace;
|
||||||
|
|
||||||
@@ -76,13 +79,24 @@ public class FileTree implements FileHandleResolver{
|
|||||||
|
|
||||||
return loadedMusic.get(musicName, () -> {
|
return loadedMusic.get(musicName, () -> {
|
||||||
String name = "music/" + musicName;
|
String name = "music/" + musicName;
|
||||||
String path = Vars.tree.get(name + ".ogg").exists() ? name + ".ogg" : name + ".mp3";
|
String path = getAudioPath(name);
|
||||||
|
|
||||||
var music = new Music();
|
var music = new Music();
|
||||||
|
|
||||||
|
if(path == null) return music;
|
||||||
var desc = Core.assets.load(path, Music.class, new MusicParameter(music));
|
var desc = Core.assets.load(path, Music.class, new MusicParameter(music));
|
||||||
desc.errored = Throwable::printStackTrace;
|
desc.errored = Throwable::printStackTrace;
|
||||||
|
|
||||||
return music;
|
return music;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static @Nullable String getAudioPath(String name){
|
||||||
|
Fi ogg = Vars.tree.get(name + ".ogg"), mp3 = Vars.tree.get(name + ".mp3");
|
||||||
|
if(ogg.exists()) return name + ".ogg";
|
||||||
|
if(mp3.exists()) return name + ".mp3";
|
||||||
|
|
||||||
|
Log.warn("Audio file not found: @ (.mp3 or .ogg)", name);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ import mindustry.entities.effect.*;
|
|||||||
import mindustry.entities.part.*;
|
import mindustry.entities.part.*;
|
||||||
import mindustry.entities.part.DrawPart.*;
|
import mindustry.entities.part.DrawPart.*;
|
||||||
import mindustry.entities.pattern.*;
|
import mindustry.entities.pattern.*;
|
||||||
|
import mindustry.entities.units.*;
|
||||||
import mindustry.game.*;
|
import mindustry.game.*;
|
||||||
import mindustry.game.Objectives.*;
|
import mindustry.game.Objectives.*;
|
||||||
import mindustry.gen.*;
|
import mindustry.gen.*;
|
||||||
@@ -62,6 +63,8 @@ public class ContentParser{
|
|||||||
Seq<ParseListener> listeners = new Seq<>();
|
Seq<ParseListener> listeners = new Seq<>();
|
||||||
/** If false, arbitrary class names cannot be resolved with Class.forName. */
|
/** If false, arbitrary class names cannot be resolved with Class.forName. */
|
||||||
boolean allowClassResolution = true;
|
boolean allowClassResolution = true;
|
||||||
|
/** If false, sound asset loading is disabled. */
|
||||||
|
boolean allowAssetLoading = true;
|
||||||
|
|
||||||
ObjectMap<Class<?>, FieldParser> classParsers = new ObjectMap<>(){{
|
ObjectMap<Class<?>, FieldParser> classParsers = new ObjectMap<>(){{
|
||||||
put(Effect.class, (type, data) -> {
|
put(Effect.class, (type, data) -> {
|
||||||
@@ -298,11 +301,20 @@ public class ContentParser{
|
|||||||
if(data.isArray()) return new RandomSound(parser.readValue(Sound[].class, data));
|
if(data.isArray()) return new RandomSound(parser.readValue(Sound[].class, data));
|
||||||
|
|
||||||
var field = fieldOpt(Sounds.class, data);
|
var field = fieldOpt(Sounds.class, data);
|
||||||
|
|
||||||
|
if(!allowAssetLoading && field == null){
|
||||||
|
warn("Sound not found: @", data.asString());
|
||||||
|
return Sounds.none;
|
||||||
|
}
|
||||||
return field != null ? field : Vars.tree.loadSound(data.asString());
|
return field != null ? field : Vars.tree.loadSound(data.asString());
|
||||||
});
|
});
|
||||||
put(Music.class, (type, data) -> {
|
put(Music.class, (type, data) -> {
|
||||||
var field = fieldOpt(Musics.class, data);
|
var field = fieldOpt(Musics.class, data);
|
||||||
|
|
||||||
|
if(!allowAssetLoading && field == null){
|
||||||
|
warn("Music not found: @", data.asString());
|
||||||
|
return new Music();
|
||||||
|
}
|
||||||
return field != null ? field : Vars.tree.loadMusic(data.asString());
|
return field != null ? field : Vars.tree.loadMusic(data.asString());
|
||||||
});
|
});
|
||||||
put(Objectives.Objective.class, (type, data) -> {
|
put(Objectives.Objective.class, (type, data) -> {
|
||||||
@@ -602,16 +614,15 @@ public class ContentParser{
|
|||||||
}else{
|
}else{
|
||||||
throw new IllegalArgumentException("Missing a valid 'block' in 'requirements'");
|
throw new IllegalArgumentException("Missing a valid 'block' in 'requirements'");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(value.has("controller") || value.has("aiController")){
|
if(value.has("controller") || value.has("aiController")){
|
||||||
unit.aiController = supply(resolve(value.getString("controller", value.getString("aiController", "")), FlyingAI.class));
|
unit.aiController = resolveController(value.getString("controller", value.getString("aiController", "")));
|
||||||
value.remove("controller");
|
value.remove("controller");
|
||||||
}
|
}
|
||||||
|
|
||||||
if(value.has("defaultController")){
|
if(value.has("defaultController")){
|
||||||
var sup = supply(resolve(value.getString("defaultController"), FlyingAI.class));
|
var sup = resolveController(value.getString("defaultController"));
|
||||||
unit.controller = u -> sup.get();
|
unit.controller = u -> sup.get();
|
||||||
value.remove("defaultController");
|
value.remove("defaultController");
|
||||||
}
|
}
|
||||||
@@ -1094,6 +1105,12 @@ public class ContentParser{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Prov<UnitController> resolveController(String type){
|
||||||
|
//this is used as a captured value to avoid parsing it multiple times
|
||||||
|
var controller = supply(resolve(type, FlyingAI.class));
|
||||||
|
return controller::get;
|
||||||
|
}
|
||||||
|
|
||||||
Object field(Class<?> type, JsonValue value){
|
Object field(Class<?> type, JsonValue value){
|
||||||
return field(type, value.asString());
|
return field(type, value.asString());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,6 +10,8 @@ import mindustry.*;
|
|||||||
import mindustry.core.*;
|
import mindustry.core.*;
|
||||||
import mindustry.ctype.*;
|
import mindustry.ctype.*;
|
||||||
import mindustry.entities.part.*;
|
import mindustry.entities.part.*;
|
||||||
|
import mindustry.entities.units.*;
|
||||||
|
import mindustry.gen.*;
|
||||||
import mindustry.type.*;
|
import mindustry.type.*;
|
||||||
import mindustry.world.*;
|
import mindustry.world.*;
|
||||||
import mindustry.world.blocks.*;
|
import mindustry.world.blocks.*;
|
||||||
@@ -54,6 +56,7 @@ public class DataPatcher{
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
cont.allowClassResolution = false;
|
cont.allowClassResolution = false;
|
||||||
|
cont.allowAssetLoading = false;
|
||||||
|
|
||||||
return cont;
|
return cont;
|
||||||
}
|
}
|
||||||
@@ -351,7 +354,14 @@ public class DataPatcher{
|
|||||||
var fields = parser.getJson().getFields(actualType);
|
var fields = parser.getJson().getFields(actualType);
|
||||||
var fdata = fields.get(field);
|
var fdata = fields.get(field);
|
||||||
var fobj = object;
|
var fobj = object;
|
||||||
if(fdata != null){
|
|
||||||
|
if(value instanceof JsonValue jsv && object instanceof UnitType && field.equals("controller")){
|
||||||
|
var fmeta = fields.get("controller");
|
||||||
|
assignValue(object, "controller", new FieldData(fmeta), () -> Reflect.get(fobj, fmeta.field), val -> Reflect.set(fobj, fmeta.field, val), (Func<Unit, UnitController>)(u -> parser.resolveController(jsv.asString()).get()), true);
|
||||||
|
}else if(value instanceof JsonValue jsv && object instanceof UnitType && field.equals("aiController")){
|
||||||
|
var fmeta = fields.get("aiController");
|
||||||
|
assignValue(object, "aiController", new FieldData(fmeta), () -> Reflect.get(fobj, fmeta.field), val -> Reflect.set(fobj, fmeta.field, val), parser.resolveController(jsv.asString()), true);
|
||||||
|
}else if(fdata != null){
|
||||||
if(checkField(fdata.field)) return;
|
if(checkField(fdata.field)) return;
|
||||||
|
|
||||||
assignValue(object, field, new FieldData(fdata), () -> Reflect.get(fobj, fdata.field), fv -> {
|
assignValue(object, field, new FieldData(fdata), () -> Reflect.get(fobj, fdata.field), fv -> {
|
||||||
|
|||||||
Reference in New Issue
Block a user