Support for zones

This commit is contained in:
Anuken 2019-10-03 18:53:43 -04:00
parent 35ede418eb
commit bc02d178ce
6 changed files with 50 additions and 7 deletions

View File

@ -78,6 +78,7 @@ mod.enable = Enable
mod.requiresrestart = The game will now close to apply the mod changes.
mod.reloadrequired = [scarlet]Reload Required
mod.import = Import Mod
mod.import.github = Import Github Mod
mod.remove.confirm = This mod will be deleted.
mod.author = [LIGHT_GRAY]Author:[] {0}
mod.missing = This save contains mods that you have recently updated or no longer have installed. Save corruption may occur. Are you sure you want to load it?\n[lightgray]Mods:\n{0}

View File

@ -284,7 +284,7 @@ public class UI implements ApplicationListener, Loadable{
new Dialog(titleText){{
cont.margin(30).add(dtext).padRight(6f);
TextFieldFilter filter = inumeric ? TextFieldFilter.digitsOnly : (f, c) -> true;
TextField field = cont.addField(def, t -> {}).size(170f, 50f).get();
TextField field = cont.addField(def, t -> {}).size(330f, 50f).get();
field.setFilter((f, c) -> field.getText().length() < textLength && filter.acceptChar(f, c));
buttons.defaults().size(120, 54).pad(4);
buttons.addButton("$ok", () -> {

View File

@ -2,11 +2,13 @@ package io.anuke.mindustry.mod;
import io.anuke.arc.*;
import io.anuke.arc.audio.*;
import io.anuke.arc.collection.Array;
import io.anuke.arc.collection.*;
import io.anuke.arc.function.*;
import io.anuke.arc.graphics.*;
import io.anuke.arc.util.ArcAnnotate.*;
import io.anuke.arc.util.*;
import io.anuke.arc.util.reflect.Field;
import io.anuke.arc.util.reflect.*;
import io.anuke.arc.util.serialization.*;
import io.anuke.arc.util.serialization.Json.*;
@ -21,6 +23,8 @@ import io.anuke.mindustry.mod.Mods.*;
import io.anuke.mindustry.type.*;
import io.anuke.mindustry.world.*;
import java.lang.reflect.*;
@SuppressWarnings("unchecked")
public class ContentParser{
private static final boolean ignoreUnknownFields = true;
@ -29,6 +33,7 @@ public class ContentParser{
put(BulletType.class, (type, data) -> field(Bullets.class, data));
put(Effect.class, (type, data) -> field(Fx.class, data));
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(Music.class, (type, data) -> {
if(fieldOpt(Musics.class, data) != null) return fieldOpt(Musics.class, data);
@ -173,7 +178,7 @@ public class ContentParser{
if(!arr.isEmpty()){
Class<?> c = arr.first().getClass();
//get base content class, skipping intermediates
while(!(c.getSuperclass() == Content.class || c.getSuperclass() == UnlockableContent.class || c.getSuperclass() == UnlockableContent.class)){
while(!(c.getSuperclass() == Content.class || c.getSuperclass() == UnlockableContent.class || Modifier.isAbstract(c.getSuperclass().getModifiers()))){
c = c.getSuperclass();
}
@ -260,13 +265,13 @@ public class ContentParser{
private void checkNulls(Object object, ObjectSet<Object> checked){
checked.add(object);
parser.getFields(object.getClass()).each((name, field) -> {
parser.getFields(object.getClass()).values().toArray().each(field -> {
try{
if(field.field.getType().isPrimitive()) return;
Object obj = field.field.get(object);
if(field.field.isAnnotationPresent(NonNull.class) && field.field.get(object) == null){
throw new RuntimeException("Field '" + name + "' in " + object.getClass().getSimpleName() + " is missing!");
throw new RuntimeException("Field '" + field.field.getName() + "' in " + object.getClass().getSimpleName() + " is missing!");
}
if(obj != null && !checked.contains(obj)){

View File

@ -331,6 +331,9 @@ public class Mods implements Loadable{
* Note that directories can be loaded as mods.*/
private LoadedMod loadMod(FileHandle sourceFile) throws Exception{
FileHandle zip = sourceFile.isDirectory() ? sourceFile : new ZipFileHandle(sourceFile);
if(zip.list().length == 1 && zip.list()[0].isDirectory()){
zip = zip.list()[0];
}
FileHandle metaf = zip.child("mod.json").exists() ? zip.child("mod.json") : zip.child("plugin.json");
if(!metaf.exists()){
@ -341,6 +344,12 @@ public class Mods implements Loadable{
ModMeta meta = json.fromJson(ModMeta.class, metaf.readString());
String camelized = meta.name.replace(" ", "");
String mainClass = meta.main == null ? camelized.toLowerCase() + "." + camelized + "Mod" : meta.main;
String baseName = meta.name.toLowerCase().replace(" ", "-");
if(loaded.contains(m -> m.name.equals(baseName)) || disabled.contains(m -> m.name.equals(baseName))){
throw new IllegalArgumentException("A mod with the name '" + baseName + "' is already imported.");
}
Mod mainMod;
FileHandle mainFile = zip;

View File

@ -47,7 +47,7 @@ public class Zone extends UnlockableContent{
@Override
public void load(){
preview = Core.atlas.find("zone-" + name);
preview = Core.atlas.find("zone-" + name, Core.atlas.find(name + "-zone"));
}
public Rules getRules(){
@ -209,14 +209,18 @@ public class Zone extends UnlockableContent{
}
public static class ZoneRequirement{
public final Zone zone;
public final int wave;
public @NonNull Zone zone;
public @NonNull int wave;
public ZoneRequirement(Zone zone, int wave){
this.zone = zone;
this.wave = wave;
}
protected ZoneRequirement(){
}
public static ZoneRequirement[] with(Object... objects){
ZoneRequirement[] out = new ZoneRequirement[objects.length / 2];
for(int i = 0; i < objects.length; i += 2){

View File

@ -3,6 +3,8 @@ package io.anuke.mindustry.ui.dialogs;
import io.anuke.arc.*;
import io.anuke.arc.collection.*;
import io.anuke.arc.util.*;
import io.anuke.arc.util.io.*;
import io.anuke.mindustry.game.*;
import io.anuke.mindustry.gen.*;
import io.anuke.mindustry.graphics.*;
import io.anuke.mindustry.mod.Mods.*;
@ -107,5 +109,27 @@ public class ModsDialog extends FloatingDialog{
}
});
}).margin(12f).width(500f);
//not well tested currently
if(Version.build == -1){
cont.row();
cont.addImageTextButton("$mod.import.github", Icon.github, () -> {
ui.showTextInput("$mod.import.github", "", "Anuken/ExampleMod", text -> {
Core.net.httpGet("http://api.github.com/repos/" + text + "/zipball/master", loc -> {
Core.net.httpGet(loc.getHeader("Location"), result -> {
try{
Streams.copyStream(result.getResultAsStream(), modDirectory.child(text.replace("/", "") + ".zip").write(false));
ui.loadAnd(() -> {
mods.reloadContent();
});
}catch(Exception e){
ui.showException(e);
}
}, ui::showException);
}, ui::showException);
});
}).margin(12f).width(500f);
}
}
}