mirror of
https://github.com/Anuken/Mindustry.git
synced 2025-03-14 11:59:20 +07:00
Support for zones
This commit is contained in:
parent
35ede418eb
commit
bc02d178ce
@ -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}
|
||||
|
@ -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", () -> {
|
||||
|
@ -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)){
|
||||
|
@ -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;
|
||||
|
@ -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){
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user