1
0
mirror of https://github.com/Anuken/Mindustry.git synced 2024-09-21 13:28:12 +03:00

Mod browser icon support

This commit is contained in:
Anuken 2021-02-06 12:05:59 -05:00
parent 7e4ffe6a7d
commit 25d013b768
10 changed files with 98 additions and 44 deletions

View File

@ -122,6 +122,7 @@ mods.openfolder = Open Folder
mods.viewcontent = View Content
mods.reload = Reload
mods.reloadexit = The game will now exit, to reload mods.
mod.installed = [[Installed]
mod.display = [gray]Mod:[orange] {0}
mod.enabled = [lightgray]Enabled
mod.disabled = [scarlet]Disabled

View File

@ -345,7 +345,7 @@ public class Vars implements Loadable{
}
public static void loadSettings(){
settings.setJson(JsonIO.json());
settings.setJson(JsonIO.json);
settings.setAppName(appName);
if(steam || (Version.modifier != null && Version.modifier.contains("steam"))){

View File

@ -435,7 +435,7 @@ public class UnitTypes implements ContentList{
firstShotDelay = Fx.greenLaserChargeSmall.lifetime - 1f;
reload = 160f;
reload = 155f;
recoil = 0f;
chargeSound = Sounds.lasercharge2;
shootSound = Sounds.beam;
@ -443,7 +443,7 @@ public class UnitTypes implements ContentList{
cooldownTime = 200f;
bullet = new ContinuousLaserBulletType(){{
damage = 23f;
damage = 24f;
length = 160f;
hitEffect = Fx.hitMeltHeal;
drawSize = 420f;
@ -454,7 +454,7 @@ public class UnitTypes implements ContentList{
shootEffect = Fx.greenLaserChargeSmall;
incendChance = 0.075f;
incendChance = 0.08f;
incendSpread = 5f;
incendAmount = 1;

View File

@ -3,6 +3,7 @@ package mindustry.entities;
import arc.math.*;
import arc.math.geom.*;
import arc.struct.*;
import mindustry.content.*;
import mindustry.gen.*;
import mindustry.world.*;
@ -126,7 +127,7 @@ public class EntityCollisions{
public static boolean legsSolid(int x, int y){
Tile tile = world.tile(x, y);
return tile == null || tile.staticDarkness() >= 2 || tile.floor().solid;
return tile == null || tile.staticDarkness() >= 2 || (tile.floor().solid && tile.block() == Blocks.air);
}
public static boolean waterSolid(int x, int y){

View File

@ -13,8 +13,9 @@ import java.io.*;
@SuppressWarnings("unchecked")
public class JsonIO{
private static CustomJson jsonBase = new CustomJson();
private static Json json = new Json(){
private static final CustomJson jsonBase = new CustomJson();
public static final Json json = new Json(){
{ apply(this); }
@Override
@ -39,10 +40,6 @@ public class JsonIO{
}
};
public static Json json(){
return json;
}
public static String write(Object object){
return json.toJson(object, object.getClass());
}
@ -69,7 +66,6 @@ public class JsonIO{
}
static void apply(Json json){
json.setIgnoreUnknownFields(true);
json.setElementType(Rules.class, "spawns", SpawnGroup.class);
json.setElementType(Rules.class, "loadout", ItemStack.class);

View File

@ -7,7 +7,7 @@ import arc.scene.ui.layout.*;
import mindustry.graphics.*;
public class BorderImage extends Image{
public float thickness = 4f;
public float thickness = 4f, pad = 0f;
public Color borderColor = Pal.gray;
public BorderImage(){
@ -40,7 +40,7 @@ public class BorderImage extends Image{
Draw.color(borderColor);
Draw.alpha(parentAlpha);
Lines.stroke(Scl.scl(thickness));
Lines.rect(x + imageX, y + imageY, imageWidth * scaleX, imageHeight * scaleY);
Lines.rect(x + imageX - pad, y + imageY - pad, imageWidth * scaleX + pad*2, imageHeight * scaleY + pad*2);
Draw.reset();
}
}

View File

@ -66,7 +66,7 @@ public class MapPlayDialog extends BaseDialog{
cont.add(selmode);
cont.row();
cont.button("@customize", Icon.settings, () -> dialog.show(rules, () -> rules = map.applyRules(selectedGamemode))).width(230);
cont.button("@customize", Icon.settings, () -> dialog.show(rules, () -> rules = map.applyRules(selectedGamemode))).height(50f).width(230);
cont.row();
cont.add(new BorderImage(map.safeTexture(), 3f)).size(mobile && !Core.graphics.isPortrait() ? 150f : 250f).get().setScaling(Scaling.fit);
//only maps with survival are valid for high scores

View File

@ -5,6 +5,7 @@ import arc.Net.*;
import arc.files.*;
import arc.func.*;
import arc.graphics.*;
import arc.graphics.Texture.*;
import arc.graphics.g2d.*;
import arc.input.*;
import arc.scene.style.*;
@ -21,6 +22,7 @@ import mindustry.ctype.*;
import mindustry.game.EventType.*;
import mindustry.gen.*;
import mindustry.graphics.*;
import mindustry.io.*;
import mindustry.mod.*;
import mindustry.mod.Mods.*;
import mindustry.ui.*;
@ -32,6 +34,8 @@ import java.util.*;
import static mindustry.Vars.*;
public class ModsDialog extends BaseDialog{
private ObjectMap<String, TextureRegion> textureCache = new ObjectMap<>();
private String searchtxt = "";
private @Nullable Seq<ModListing> modList;
private boolean orderDate = true;
@ -44,6 +48,15 @@ public class ModsDialog extends BaseDialog{
super("@mods");
addCloseButton();
Events.on(DisposeEvent.class, e -> {
textureCache.each((key, val) -> {
if(val.texture.width == val.width){
val.texture.dispose();
}
});
textureCache.clear();
});
browser = new BaseDialog("@mods.browser");
browser.cont.table(table -> {
@ -122,9 +135,7 @@ public class ModsDialog extends BaseDialog{
ui.showErrorMessage(Core.bundle.format("connectfail", status));
}else{
try{
var j = new Json();
j.setIgnoreUnknownFields(true);
modList = j.fromJson(Seq.class, ModListing.class, strResult);
modList = JsonIO.json.fromJson(Seq.class, ModListing.class, strResult);
var d = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
Func<String, Date> parser = text -> {
@ -397,7 +408,7 @@ public class ModsDialog extends BaseDialog{
browserTable.clear();
browserTable.add("@loading");
int cols = Math.max(Core.graphics.getWidth() / 475, 1);
int cols = Math.max(Core.graphics.getWidth() / 482, 1);
getModList(rlistings -> {
browserTable.clear();
@ -412,23 +423,65 @@ public class ModsDialog extends BaseDialog{
for(ModListing mod : listings){
if((mod.hasJava && Vars.ios) || !searchtxt.isEmpty() && !mod.repo.toLowerCase().contains(searchtxt.toLowerCase()) || (Vars.ios && mod.hasScripts)) continue;
browserTable.button(btn -> {
btn.top().left();
btn.margin(12f);
btn.table(con -> {
con.left();
con.add(
"[accent]" + mod.name.replace("\n", "") +
(installed.contains(mod.repo) ? " [scarlet][[Installed]" : "") +
"[white]\n[lightgray]Author:[] " + trimText(mod.author) +
"\n[lightgray]\uE809 " + mod.stars +
(Version.isAtLeast(mod.minGameVersion) ? "" : "\n" + Core.bundle.format("mod.requiresversion", mod.minGameVersion)))
.width(388f).wrap().growX().pad(0f, 6f, 0f, 6f).left().labelAlign(Align.left);
con.add().growX().pad(0f, 6f, 0f, 6f);
}).fillY().growX().pad(0f, 6f, 0f, 6f);
}, Styles.modsb, () -> {
float s = 64f;
browserTable.button(con -> {
con.margin(0f);
con.left();
String repo = mod.repo;
con.add(new BorderImage(){
TextureRegion last;
{
border(installed.contains(repo) ? Pal.accent : Color.lightGray);
setDrawable(Tex.nomap);
pad = Scl.scl(4f);
}
@Override
public void draw(){
super.draw();
//textures are only requested when the rendering happens; this assists with culling
if(!textureCache.containsKey(repo)){
textureCache.put(repo, last = Tex.nomap.getRegion());
Core.net.httpGet("https://raw.githubusercontent.com/Anuken/MindustryMods/master/icons/" + repo.replace("/", "_"), res -> {
if(res.getStatus() == HttpStatus.OK){
Pixmap pix = new Pixmap(res.getResult());
Core.app.post(() -> {
try{
var tex = new Texture(pix);
tex.setFilter(TextureFilter.linear);
textureCache.put(repo, new TextureRegion(tex));
pix.dispose();
}catch(Exception e){
Log.err(e);
}
});
}
}, err -> {});
}
var next = textureCache.get(repo);
if(last != next){
last = next;
setDrawable(next);
}
}
}).size(s).pad(4f * 2f);
con.add(
"[accent]" + mod.name.replace("\n", "") +
(installed.contains(mod.repo) ? "\n[lightgray]" + Core.bundle.get("mod.installed") : "") +
//"[white]\n[lightgray]Author:[] " + trimText(mod.author) +
"\n[lightgray]\uE809 " + mod.stars +
(Version.isAtLeast(mod.minGameVersion) ? "" : "\n" + Core.bundle.format("mod.requiresversion", mod.minGameVersion)))
.width(358f).wrap().grow().pad(4f, 2f, 4f, 6f).top().left().labelAlign(Align.topLeft);
}, Styles.clearPartialt, () -> {
var sel = new BaseDialog(mod.name);
sel.cont.add(mod.description).width(mobile ? 400f : 500f).wrap().pad(4f).labelAlign(Align.center, Align.left);
sel.cont.add(mod.description + "\n\n[accent]" + Core.bundle.get("editor.author") + "[lightgray] " + mod.author).width(mobile ? 400f : 500f).wrap().pad(4f).labelAlign(Align.center, Align.left);
sel.buttons.defaults().size(150f, 54f).pad(2f);
sel.setFillParent(false);
sel.buttons.button("@back", Icon.left, () -> {
@ -447,7 +500,8 @@ public class ModsDialog extends BaseDialog{
sel.keyDown(KeyCode.escape, sel::hide);
sel.keyDown(KeyCode.back, sel::hide);
sel.show();
}).width(460f).growX().left().fillY();
}).width(460f).pad(4).growX().left().height(s + 8*2f).fillY();
if(++i % cols == 0) browserTable.row();
}
});
@ -485,11 +539,13 @@ public class ModsDialog extends BaseDialog{
}
private void githubImportMod(String repo, boolean isJava){
ui.loadfrag.show();
if(isJava){
githubImportJavaMod(repo);
ui.showConfirm("@warning", "@mod.jarwarn", () -> {
ui.loadfrag.show();
githubImportJavaMod(repo);
});
}else{
ui.loadfrag.show();
Core.net.httpGet(ghApi + "/repos/" + repo, res -> {
if(checkError(res)){
var json = Jval.read(res.getResultAsString());

View File

@ -1,3 +1,3 @@
org.gradle.daemon=true
org.gradle.jvmargs=-Xms256m -Xmx1024m
archash=f7e9cc8f62d2509fc4c508442b082bdc88692b42
archash=c9986a9770c3d287939399f3ae7171390cb1ae24

View File

@ -238,8 +238,8 @@ public class ServerControl implements ApplicationListener{
Events.on(PlayEvent.class, e -> {
try{
JsonValue value = JsonIO.json().fromJson(null, Core.settings.getString("globalrules"));
JsonIO.json().readFields(state.rules, value);
JsonValue value = JsonIO.json.fromJson(null, Core.settings.getString("globalrules"));
JsonIO.json.readFields(state.rules, value);
}catch(Throwable t){
err("Error applying custom rules, proceeding without them.", t);
}
@ -433,7 +433,7 @@ public class ServerControl implements ApplicationListener{
handler.register("rules", "[remove/add] [name] [value...]", "List, remove or add global rules. These will apply regardless of map.", arg -> {
String rules = Core.settings.getString("globalrules");
JsonValue base = JsonIO.json().fromJson(null, rules);
JsonValue base = JsonIO.json.fromJson(null, rules);
if(arg.length == 0){
info("Rules:\n@", JsonIO.print(rules));
@ -467,7 +467,7 @@ public class ServerControl implements ApplicationListener{
JsonValue parent = new JsonValue(ValueType.object);
parent.addChild(value);
JsonIO.json().readField(state.rules, value.name, parent);
JsonIO.json.readField(state.rules, value.name, parent);
if(base.has(value.name)){
base.remove(value.name);
}