From 82779a9d8cb6594f6375f478bf943ec52ad78463 Mon Sep 17 00:00:00 2001 From: Slotterleet <62336673+Slotterleet@users.noreply.github.com> Date: Fri, 6 Sep 2024 20:43:34 +0300 Subject: [PATCH] Mod's core code polishing and improvement --- res/bundles/bundle.properties | 2 +- src/fos/core/FOSEventTypes.java | 2 + src/fos/core/FOSMod.java | 173 +++----------------------- src/fos/core/RichPresenceHandler.java | 87 +++++++++++++ src/fos/ui/UIHandler.java | 123 ++++++++++++++++++ 5 files changed, 227 insertions(+), 160 deletions(-) create mode 100644 src/fos/core/RichPresenceHandler.java create mode 100644 src/fos/ui/UIHandler.java diff --git a/res/bundles/bundle.properties b/res/bundles/bundle.properties index 1f4be25..1eb0b40 100644 --- a/res/bundles/bundle.properties +++ b/res/bundles/bundle.properties @@ -71,7 +71,7 @@ setting.fos-menutheme.caldemoltsystem = Caldemolt Star System setting.fos-menutheme.lumoniterrain = Lumoni (Terrain) setting.fos-rotatemenucamera.name = Rotate Menu Camera setting.fos-rotatemenucamera.description = If a space theme is chosen, the camera will rotate around the planet. -setting.fos-realisticmode.name = ""Realistic"" Mode +setting.fos-realisticmode.name = Realistic Mode setting.fos-realisticmode.description = Disable SFX in places without atmosphere. setting.fos-ostdontshowagain.name = Don't Show Prompt on Startup setting.fos-ostdontshowagain.description = Disable a prompt to download FOS OST on game startup. diff --git a/src/fos/core/FOSEventTypes.java b/src/fos/core/FOSEventTypes.java index 8ad9793..91f62bd 100644 --- a/src/fos/core/FOSEventTypes.java +++ b/src/fos/core/FOSEventTypes.java @@ -11,4 +11,6 @@ public InsectDeathEvent(Tile tile) { this.tile = tile; } } + + public static class RealisticToggleEvent {} } diff --git a/src/fos/core/FOSMod.java b/src/fos/core/FOSMod.java index 1841017..c33520e 100644 --- a/src/fos/core/FOSMod.java +++ b/src/fos/core/FOSMod.java @@ -5,13 +5,10 @@ import arc.backend.sdl.SdlApplication; import arc.backend.sdl.jni.SDL; import arc.graphics.*; -import arc.graphics.g2d.*; +import arc.graphics.g2d.ScreenQuad; import arc.graphics.gl.Shader; import arc.input.*; import arc.math.Mathf; -import arc.scene.*; -import arc.scene.ui.ImageButton; -import arc.scene.ui.layout.*; import arc.struct.Seq; import arc.util.*; import fos.content.*; @@ -20,19 +17,15 @@ import fos.graphics.*; import fos.graphics.cachelayers.FOSCacheLayers; import fos.net.FOSCall; -import fos.ui.menus.*; -import mindustry.game.*; +import fos.ui.UIHandler; +import fos.ui.menus.FOSMenus; +import mindustry.game.EventType; import mindustry.gen.*; -import mindustry.graphics.Layer; import mindustry.mod.Mod; -import mindustry.mod.Mods.LoadedMod; -import mindustry.ui.Styles; -import mindustry.ui.dialogs.PlanetDialog; import java.util.Calendar; import static arc.Core.*; -import static arc.discord.DiscordRPC.*; import static arc.input.GestureDetector.GestureListener; import static mindustry.Vars.*; @@ -63,41 +56,7 @@ public FOSMod() { } }); - Events.run(EventType.Trigger.update, () -> { - if (!mobile) { - boolean useDiscord = !OS.hasProp("nodiscord"); - if (useDiscord) { - var planet = state.rules.planet; - - if (planet != null && !planet.isVanilla() && planet.minfo.mod == FOSVars.mod) { - RichPresence presence = new RichPresence(); - - String gameMapWithWave, gameMode = "", gamePlayersSuffix = ""; - - gameMapWithWave = Strings.capitalize(Strings.stripColors(state.map.name())); - - if(state.rules.waves){ - gameMapWithWave += " | Wave " + state.wave; - } - gameMode = state.rules.pvp ? "PvP" : state.rules.attackMode ? "Attack" : state.rules.infiniteResources ? "Sandbox" : "Survival"; - if(net.active() && Groups.player.size() > 1){ - gamePlayersSuffix = " | " + Groups.player.size() + " Players"; - } - - presence.details = "[FOS] " + gameMapWithWave; - presence.state = gameMode + gamePlayersSuffix; - - presence.largeImageKey = "logo"; - - try { - send(presence); - } catch (Exception ignored) {} - } - } - } - - //realistic mode - no sound FX in places with no atmosphere, such as asteroids - // FIXME запхнуть в таймер и менять звук только при изменении настроек и загрузке + Events.on(FOSEventTypes.RealisticToggleEvent.class, e -> { if (settings.getBool("fos-realisticmode") && state.rules.sector != null && !state.rules.sector.planet.hasAtmosphere) { audio.soundBus.setVolume(0f); } else { @@ -151,30 +110,6 @@ public void init() { //anything after this is client-side only. if (headless) return; - //debug-only insect pathfinder test - if (settings.getBool("fos-pathfinder-debug", false)) { - Events.run(EventType.Trigger.draw, () -> { - for (int i = 0; i < FOSVars.deathMapController.deathMap.length; i++) { - if (FOSVars.deathMapController.deathMap[i] == 0) continue; - - Draw.z(Layer.light); - Draw.alpha(FOSVars.deathMapController.deathMap[i] / 100f); - - Draw.rect("empty", world.tiles.geti(i).worldx(), world.tiles.geti(i).worldy()); - - Draw.reset(); - } - }); - } - - //an anti-cheat system from long ago, is it really necessary now? - LoadedMod xf = mods.list().find(m -> - /* some mods don't even have the author field, apparently. how stupid. */ m.meta.author != null && - (m.meta.author.equals("XenoTale") || m.meta.author.equals("goldie"))); - if (xf != null) { - ui.showOkText("@fos.errortitle", bundle.format("fos.errortext", xf.meta.displayName), () -> app.exit()); - } - SplashTexts.init(); if (FOSVars.isAprilFools) @@ -187,19 +122,6 @@ public void init() { FOSIcons.load(); FOSMenus.load(); - //add a couple of buttons to in-game editor - ui.editor.shown(this::addEditorTeams); - - //add a new font page for... reasons - //FIXME -/* - Seq fonts = Seq.with(Fonts.def, Fonts.outline); - fonts.each(f -> { - var regions = f.getRegions(); - regions.add(new TextureRegion()); - }); -*/ - //init modded teams FOSTeams.load(); } @@ -223,61 +145,14 @@ public void clientLoaded() { } } - //load this mod's settings + // load this mod's settings constructSettings(); - //disclaimer for non-debug - if (FOSVars.earlyAccess && !FOSVars.debug) - ui.showOkText("@fos.earlyaccesstitle", bundle.get("fos.earlyaccess"), () -> {}); - - //unsupported on bleeding-edge notice - if (becontrol.active()) - ui.showOkText("@fos.beunsupportedtitle", bundle.get("fos.beunsupported"), () -> {}); - - //unlock every planet if debug - if (FOSVars.debug) - PlanetDialog.debugSelect = true; - - //check for "Fictional Octo System OST" mod. if it doesn't exist, prompt to download from GitHub - LoadedMod ost = mods.getMod("fosost"); - if (ost == null) { - if (!settings.getBool("fos-ostdontshowagain")) { - ui.showCustomConfirm("@fos.noosttitle", bundle.get("fos.noost"), - "@mods.browser.add", "@no", - () -> { - ui.mods.githubImportMod("TeamOct/FOS-OST", true); - }, - () -> {}); - } - } else if (!ost.enabled()) { - ui.showCustomConfirm("@fos.ostdisabledtitle", bundle.get("fos.ostdisabled"), - "@yes", "@no", - () -> { - mods.setEnabled(ost, true); - ui.showInfoOnHidden("@mods.reloadexit", () -> app.exit()); - }, () -> {}); - } - - Element menu = ((Element) Reflect.get(ui.menufrag, "container")).parent.parent; - Group menuCont = menu.parent; - menuCont.addChildBefore(menu, new Element(){ - @Override - public void draw() { - FOSVars.menuRenderer.render(); - } - }); + // setup UI + UIHandler.init(); - int tn = settings.getInt("fos-menutheme"); - MenuBackground bg = ( - tn == 2 ? FOSMenus.uxerdSpace : - tn == 3 ? FOSMenus.lumoniSpace : - tn == 4 ? FOSMenus.random : - tn == 5 ? FOSMenus.solarSystem : - tn == 6 ? FOSMenus.caldemoltSystem : - tn == 7 ? FOSMenus.lumoniTerrain : null); - if (bg != null) { - FOSVars.menuRenderer.changeBackground(bg); - } + // setup Discord RPC + RichPresenceHandler.init(); // add modded hints FOSVars.hints.load(); @@ -321,10 +196,12 @@ public void constructSettings() { t.sliderPref("fos-damagedisplayfrequency", 30, 3, 120, 3, s -> bundle.format("setting.seconds", s / 60f)); t.checkPref("fos-ostdontshowagain", false); - t.checkPref("fos-realisticmode", false); + t.checkPref("fos-realisticmode", false, b -> + Events.fire(new FOSEventTypes.RealisticToggleEvent()) + ); t.checkPref("fos-refreshsplash", false, b -> { Time.run(60f, () -> - settings.put("fos-refreshsplash", false) + settings.put("fos-refreshsplash", false) ); int n = Mathf.floor((float) Math.random() * SplashTexts.splashes.size); mods.locateMod("fos").meta.subtitle = SplashTexts.splashes.get(n); @@ -340,28 +217,6 @@ public void constructSettings() { }); } - public void addEditorTeams() { - //java sucks - WidgetGroup teambuttons = (WidgetGroup) ui.editor.getChildren().get(0); - teambuttons = (WidgetGroup)teambuttons.getChildren().get(0); - teambuttons = (WidgetGroup)teambuttons.getChildren().get(0); - - ((Table)teambuttons).row(); - - for (int i = 69; i <= 70; i++) { - Team team = Team.get(i); - - ImageButton button = new ImageButton(Tex.whiteui, Styles.clearNoneTogglei); - button.margin(4f); - button.getImageCell().grow(); - button.getStyle().imageUpColor = team.color; - button.clicked(() -> editor.drawTeam = team); - button.update(() -> button.setChecked(editor.drawTeam == team)); - - ((Table)teambuttons).add(button); - } - } - void superSecretThings() { if (mobile) return; diff --git a/src/fos/core/RichPresenceHandler.java b/src/fos/core/RichPresenceHandler.java new file mode 100644 index 0000000..8c13769 --- /dev/null +++ b/src/fos/core/RichPresenceHandler.java @@ -0,0 +1,87 @@ +package fos.core; + +import arc.discord.DiscordRPC; +import arc.util.*; +import mindustry.gen.Groups; + +import static arc.discord.DiscordRPC.RichPresence; +import static mindustry.Vars.*; + +public class RichPresenceHandler { + public static final long appId = 1281506459309441074L; + public static RichPresence presence = new RichPresence(); + + public static void init() { + if (mobile) return; + + presence.startTimestamp = System.currentTimeMillis(); + + try { + // close vanilla RP + Log.info("[FOS] Closing vanilla Discord rich presence."); + DiscordRPC.close(); + // there's no way Vars.platform isn't DesktopLauncher at any given moment + Reflect.set(platform, "useDiscord", false); + + // then open our own one + Log.info("[FOS] Opening modded Discord rich presence."); + DiscordRPC.connect(appId); + + send(); + } catch (Exception e) { + Log.err("[FOS] Modded rich presence failed to initialize!", e); + return; + } + + Timer.schedule(RichPresenceHandler::send, 0f, 5f, -1); + } + + static void send() { + boolean useDiscord = !OS.hasProp("nodiscord"); + if (useDiscord) { + try { + var planet = state.rules.planet; + boolean isFOS = planet != null && !planet.isVanilla() && planet.minfo.mod == FOSVars.mod; + + String gameMode = "", gamePlayersSuffix = "", uiState = ""; + + if (state.isGame()) { + String gameMapWithWave; + gameMapWithWave = Strings.capitalize(Strings.stripColors(state.map.name())); + + if (state.rules.waves) { + gameMapWithWave += " | Wave " + state.wave; + } + gameMode = state.rules.pvp ? "PvP" : state.rules.attackMode ? "Attack" : state.rules.infiniteResources ? "Sandbox" : "Survival"; + if (net.active() && Groups.player.size() > 1) { + gamePlayersSuffix = " | " + Groups.player.size() + " Players"; + } + + presence.details = (isFOS ? "[FOS] " : "") + gameMapWithWave; + presence.state = gameMode + gamePlayersSuffix; + } else { + if (ui.editor != null && ui.editor.isShown()) { + uiState = "In Editor"; + } else if (ui.planet != null && ui.planet.isShown()) { + uiState = "In Launch Selection"; + } else { + uiState = "In Menu"; + } + + presence.details = ""; + presence.state = uiState; + } + + presence.largeImageKey = "logo"; + presence.label1 = "Try FOS now!"; + presence.url1 = "https://github.com/teamoct/fos/releases/latest"; + + DiscordRPC.send(presence); + + + } catch (Exception e) { + Log.err("[FOS] Rich Presence failed to send!", e); + } + } + } +} diff --git a/src/fos/ui/UIHandler.java b/src/fos/ui/UIHandler.java new file mode 100644 index 0000000..e8df808 --- /dev/null +++ b/src/fos/ui/UIHandler.java @@ -0,0 +1,123 @@ +package fos.ui; + +import arc.Events; +import arc.graphics.g2d.Draw; +import arc.scene.*; +import arc.scene.ui.ImageButton; +import arc.scene.ui.layout.*; +import arc.util.Reflect; +import fos.core.FOSVars; +import fos.ui.menus.*; +import mindustry.game.*; +import mindustry.gen.Tex; +import mindustry.graphics.Layer; +import mindustry.mod.Mods; +import mindustry.ui.Styles; +import mindustry.ui.dialogs.PlanetDialog; + +import static arc.Core.*; +import static mindustry.Vars.*; + +public class UIHandler { + public static void init() { + // disclaimer for non-debug + if (FOSVars.earlyAccess && !FOSVars.debug) + ui.showOkText("@fos.earlyaccesstitle", bundle.get("fos.earlyaccess"), () -> {}); + + // unsupported on bleeding-edge notice + if (becontrol.active()) + ui.showOkText("@fos.beunsupportedtitle", bundle.get("fos.beunsupported"), () -> {}); + + // unlock every planet if debug + if (FOSVars.debug) + PlanetDialog.debugSelect = true; + + // check for "Fictional Octo System OST" mod. if it doesn't exist, prompt to download from GitHub + Mods.LoadedMod ost = mods.getMod("fosost"); + if (ost == null) { + if (!settings.getBool("fos-ostdontshowagain")) { + ui.showCustomConfirm("@fos.noosttitle", bundle.get("fos.noost"), + "@mods.browser.add", "@no", + () -> { + ui.mods.githubImportMod("TeamOct/FOS-OST", true); + }, + () -> {}); + } + } else if (!ost.enabled()) { + ui.showCustomConfirm("@fos.ostdisabledtitle", bundle.get("fos.ostdisabled"), + "@yes", "@no", + () -> { + mods.setEnabled(ost, true); + ui.showInfoOnHidden("@mods.reloadexit", () -> app.exit()); + }, () -> {}); + } + + Element menu = ((Element) Reflect.get(ui.menufrag, "container")).parent.parent; + Group menuCont = menu.parent; + menuCont.addChildBefore(menu, new Element(){ + @Override + public void draw() { + FOSVars.menuRenderer.render(); + } + }); + + int tn = settings.getInt("fos-menutheme"); + MenuBackground bg = ( + tn == 2 ? FOSMenus.uxerdSpace : + tn == 3 ? FOSMenus.lumoniSpace : + tn == 4 ? FOSMenus.random : + tn == 5 ? FOSMenus.solarSystem : + tn == 6 ? FOSMenus.caldemoltSystem : + tn == 7 ? FOSMenus.lumoniTerrain : null); + if (bg != null) { + FOSVars.menuRenderer.changeBackground(bg); + } + + ui.editor.shown(() -> { + // java sucks + WidgetGroup teambuttons = (WidgetGroup) ui.editor.getChildren().get(0); + teambuttons = (WidgetGroup)teambuttons.getChildren().get(0); + teambuttons = (WidgetGroup)teambuttons.getChildren().get(0); + + ((Table)teambuttons).row(); + + for (int i = 69; i <= 70; i++) { + Team team = Team.get(i); + + ImageButton button = new ImageButton(Tex.whiteui, Styles.clearNoneTogglei); + button.margin(4f); + button.getImageCell().grow(); + button.getStyle().imageUpColor = team.color; + button.clicked(() -> editor.drawTeam = team); + button.update(() -> button.setChecked(editor.drawTeam == team)); + + ((Table)teambuttons).add(button); + } + }); + + // an anti-cheat system from long ago, is it really necessary now? + Mods.LoadedMod xf = mods.list().find(m -> + /* some mods don't even have the author field, apparently. how stupid. */ m.meta.author != null && + (m.meta.author.equals("XenoTale") || m.meta.author.equals("goldie"))); + if (xf != null) { + ui.showOkText("@fos.errortitle", bundle.format("fos.errortext", xf.meta.displayName), () -> app.exit()); + } + + + // debug-only insect pathfinder test + if (settings.getBool("fos-pathfinder-debug", false)) { + Events.run(EventType.Trigger.draw, () -> { + for (int i = 0; i < FOSVars.deathMapController.deathMap.length; i++) { + if (FOSVars.deathMapController.deathMap[i] == 0) continue; + + Draw.z(Layer.light); + Draw.alpha(FOSVars.deathMapController.deathMap[i] / 100f); + + Draw.rect("empty", world.tiles.geti(i).worldx(), world.tiles.geti(i).worldy()); + + Draw.reset(); + } + }); + } + } +}