More mod content support
This commit is contained in:
@@ -22,6 +22,7 @@ import io.anuke.mindustry.gen.*;
|
||||
import io.anuke.mindustry.mod.Mods.*;
|
||||
import io.anuke.mindustry.type.*;
|
||||
import io.anuke.mindustry.world.*;
|
||||
import io.anuke.mindustry.world.consumers.*;
|
||||
|
||||
import java.lang.reflect.*;
|
||||
|
||||
@@ -35,6 +36,13 @@ public class ContentParser{
|
||||
put(StatusEffect.class, (type, data) -> field(StatusEffects.class, data));
|
||||
put(Loadout.class, (type, data) -> field(Loadouts.class, data));
|
||||
put(Color.class, (type, data) -> Color.valueOf(data.asString()));
|
||||
put(BulletType.class, (type, data) -> {
|
||||
Class<? extends BulletType> bc = data.has("type") ? resolve(data.getString("type"), "io.anuke.mindustry.entities.bullets") : BasicBulletType.class;
|
||||
data.remove("type");
|
||||
BulletType result = bc.getDeclaredConstructor().newInstance();
|
||||
readFields(result, data);
|
||||
return result;
|
||||
});
|
||||
put(Music.class, (type, data) -> {
|
||||
if(fieldOpt(Musics.class, data) != null) return fieldOpt(Musics.class, data);
|
||||
|
||||
@@ -57,12 +65,18 @@ public class ContentParser{
|
||||
* This is done to accomodate binding of content names first.*/
|
||||
private Array<Runnable> reads = new Array<>();
|
||||
private LoadedMod currentMod;
|
||||
private Content currentContent;
|
||||
|
||||
private Json parser = new Json(){
|
||||
public <T> T readValue(Class<T> type, Class elementType, JsonValue jsonData){
|
||||
@Override
|
||||
public <T> T readValue(Class<T> type, Class elementType, JsonValue jsonData, Class keyType){
|
||||
if(type != null){
|
||||
if(classParsers.containsKey(type)){
|
||||
return (T)classParsers.get(type).parse(type, jsonData);
|
||||
try{
|
||||
return (T)classParsers.get(type).parse(type, jsonData);
|
||||
}catch(Exception e){
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
if(Content.class.isAssignableFrom(type)){
|
||||
@@ -70,16 +84,21 @@ public class ContentParser{
|
||||
String prefix = currentMod != null ? currentMod.name + "-" : "";
|
||||
T one = (T)Vars.content.getByName(ctype, prefix + jsonData.asString());
|
||||
if(one != null) return one;
|
||||
return (T)Vars.content.getByName(ctype, jsonData.asString());
|
||||
T two = (T)Vars.content.getByName(ctype, jsonData.asString());
|
||||
|
||||
if(two != null) return two;
|
||||
throw new IllegalArgumentException("No " + ctype + " found with name: '" + jsonData.asString() + "'");
|
||||
}
|
||||
}
|
||||
|
||||
return super.readValue(type, elementType, jsonData);
|
||||
return super.readValue(type, elementType, jsonData, keyType);
|
||||
}
|
||||
};
|
||||
|
||||
private ObjectMap<ContentType, TypeParser<?>> parsers = ObjectMap.of(
|
||||
ContentType.block, (TypeParser<Block>)(mod, name, value) -> {
|
||||
readBundle(ContentType.block, name, value);
|
||||
|
||||
//TODO generate dynamically instead of doing.. this
|
||||
Class<? extends Block> type = resolve(value.getString("type"),
|
||||
"io.anuke.mindustry.world",
|
||||
@@ -100,19 +119,17 @@ public class ContentParser{
|
||||
if(value.has("consumes")){
|
||||
for(JsonValue child : value.get("consumes")){
|
||||
if(child.name.equals("item")){
|
||||
if(child.isString()){
|
||||
block.consumes.item(Vars.content.getByName(ContentType.item, child.asString()));
|
||||
}else{
|
||||
ItemStack stack = parser.readValue(ItemStack.class, child);
|
||||
block.consumes.item(stack.item, stack.amount);
|
||||
}
|
||||
block.consumes.item(Vars.content.getByName(ContentType.item, child.asString()));
|
||||
}else if(child.name.equals("items")){
|
||||
block.consumes.items(parser.readValue(ItemStack[].class, child));
|
||||
block.consumes.add((Consume)parser.readValue(ConsumeItems.class, child));
|
||||
}else if(child.name.equals("liquid")){
|
||||
LiquidStack stack = parser.readValue(LiquidStack.class, child);
|
||||
block.consumes.liquid(stack.liquid, stack.amount);
|
||||
block.consumes.add((Consume)parser.readValue(ConsumeLiquid.class, child));
|
||||
}else if(child.name.equals("power")){
|
||||
block.consumes.power(child.asFloat());
|
||||
if(child.isDouble()){
|
||||
block.consumes.power(child.asFloat());
|
||||
}else{
|
||||
block.consumes.add((Consume)parser.readValue(ConsumePower.class, child));
|
||||
}
|
||||
}else if(child.name.equals("powerBuffered")){
|
||||
block.consumes.powerBuffered(child.asFloat());
|
||||
}else{
|
||||
@@ -138,6 +155,8 @@ public class ContentParser{
|
||||
return block;
|
||||
},
|
||||
ContentType.unit, (TypeParser<UnitType>)(mod, name, value) -> {
|
||||
readBundle(ContentType.unit, name, value);
|
||||
|
||||
Class<BaseUnit> type = resolve(value.getString("type"), "io.anuke.mindustry.entities.type.base");
|
||||
UnitType unit = new UnitType(mod + "-" + name, supply(type));
|
||||
read(() -> readFields(unit, value, true));
|
||||
@@ -156,6 +175,8 @@ public class ContentParser{
|
||||
if(Vars.content.getByName(type, name) != null){
|
||||
item = (T)Vars.content.getByName(type, name);
|
||||
}else{
|
||||
readBundle(type, name, value);
|
||||
|
||||
item = constructor.get(mod + "-" + name);
|
||||
}
|
||||
read(() -> readFields(item, value));
|
||||
@@ -163,6 +184,22 @@ public class ContentParser{
|
||||
};
|
||||
}
|
||||
|
||||
private void readBundle(ContentType type, String name, JsonValue value){
|
||||
String entryName = type + "." + currentMod.name + "-" + name + ".";
|
||||
I18NBundle bundle = Core.bundle;
|
||||
while(bundle.getParent() != null) bundle = bundle.getParent();
|
||||
|
||||
if(value.has("name")){
|
||||
bundle.getProperties().put(entryName + "name", value.getString("name"));
|
||||
value.remove("name");
|
||||
}
|
||||
|
||||
if(value.has("description")){
|
||||
bundle.getProperties().put(entryName + "description", value.getString("description"));
|
||||
value.remove("description");
|
||||
}
|
||||
}
|
||||
|
||||
/** Call to read a content's extra info later.*/
|
||||
private void read(Runnable run){
|
||||
LoadedMod mod = currentMod;
|
||||
@@ -308,7 +345,7 @@ public class ContentParser{
|
||||
}
|
||||
Field field = metadata.field;
|
||||
try{
|
||||
field.set(object, parser.readValue(field.getType(), metadata.elementType, child));
|
||||
field.set(object, parser.readValue(field.getType(), metadata.elementType, child, metadata.keyType));
|
||||
}catch(ReflectionException ex){
|
||||
throw new SerializationException("Error accessing field: " + field.getName() + " (" + type.getName() + ")", ex);
|
||||
}catch(SerializationException ex){
|
||||
@@ -324,7 +361,7 @@ public class ContentParser{
|
||||
}
|
||||
|
||||
/** Tries to resolve a class from a list of potential class names. */
|
||||
private <T> Class<T> resolve(String base, String... potentials) throws Exception{
|
||||
private <T> Class<T> resolve(String base, String... potentials){
|
||||
for(String type : potentials){
|
||||
try{
|
||||
return (Class<T>)Class.forName(type + '.' + base);
|
||||
@@ -335,7 +372,7 @@ public class ContentParser{
|
||||
}
|
||||
|
||||
private interface FieldParser{
|
||||
Object parse(Class<?> type, JsonValue value);
|
||||
Object parse(Class<?> type, JsonValue value) throws Exception;
|
||||
}
|
||||
|
||||
private interface TypeParser<T extends Content>{
|
||||
|
||||
@@ -121,7 +121,7 @@ public class Mods implements Loadable{
|
||||
|
||||
//get textures packed
|
||||
if(totalSprites > 0){
|
||||
TextureFilter filter = Core.settings.getBool("linear") ? TextureFilter.Linear : TextureFilter.Nearest;
|
||||
TextureFilter filter = TextureFilter.Nearest;
|
||||
|
||||
packer.updateTextureAtlas(Core.atlas, filter, filter, false);
|
||||
//generate new icons
|
||||
@@ -175,7 +175,7 @@ public class Mods implements Loadable{
|
||||
}
|
||||
}
|
||||
|
||||
//load mods now
|
||||
//load workshop mods now
|
||||
for(FileHandle file : platform.getExternalMods()){
|
||||
try{
|
||||
LoadedMod mod = loadMod(file, true);
|
||||
@@ -185,7 +185,7 @@ public class Mods implements Loadable{
|
||||
disabled.add(mod);
|
||||
}
|
||||
}catch(Exception e){
|
||||
Log.err("Failed to load mod file {0}. Skipping.", file);
|
||||
Log.err("Failed to load mod workshop file {0}. Skipping.", file);
|
||||
Log.err(e);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user