From 6e74912dce831a4ca29177fd6a400360e7324212 Mon Sep 17 00:00:00 2001 From: S0ly <86328249+S0ly@users.noreply.github.com> Date: Fri, 30 Oct 2026 19:52:53 +0100 Subject: [PATCH] New UI, HUD and menus --- .../reignofnether/ClientModConfigs.java | 2 +- .../reignofnether/ClientModEvents.java | 6 + .../alliance/AlliancesClient.java | 9 +- .../alliance/AlliancesServerEvents.java | 14 +- .../reignofnether/alliance/AllyCommand.java | 45 +- .../building/BuildingClientEvents.java | 43 +- .../building/BuildingPlaceButton.java | 3 + .../building/BuildingPlacement.java | 1 + .../building/BuildingServerEvents.java | 2 +- .../buildings/placements/BeaconPlacement.java | 8 +- .../CustomBuildingClientEvents.java | 57 +- .../custombuilding/CustomBuildingMenu.java | 850 +++---- .../production/ProductionItemList.java | 4 +- .../production/StartProductionButton.java | 4 + .../reignofnether/chat/ChatLines.java | 102 + .../reignofnether/chat/ChatLog.java | 107 + .../reignofnether/chat/ChatPanel.java | 281 +++ .../reignofnether/chat/SpectatorFeed.java | 78 + .../reignofnether/chat/SystemMessage.java | 31 + .../config/ReignOfNetherClientConfigs.java | 22 +- .../config/ReignOfNetherConfigScreen.java | 93 - .../config/elements/ConfigCheckbox.java | 46 - .../config/elements/ConfigColorButton.java | 115 - .../reignofnether/config/elements/Label.java | 38 - .../cursor/CursorClientEvents.java | 38 +- .../debug/RtsDebugClientEvents.java | 60 +- .../reignofnether/faction/Faction.java | 4 +- .../fogofwar/FogChunkSnapshot.java | 7 + .../fogofwar/FogOfWarClientEvents.java | 16 +- .../fogofwar/FogOfWarServerEvents.java | 36 +- .../gamerules/GameruleAction.java | 3 +- .../gamerules/GameruleClient.java | 327 +-- .../gamerules/GameruleServerEvents.java | 2 - .../gamerules/GameruleServerboundPacket.java | 32 +- .../guiscreen/TopdownGuiClientEvents.java | 4 +- .../healthbars/HealthBarClientEvents.java | 137 +- .../reignofnether/hero/HeroClientEvents.java | 3 +- .../reignofnether/hero/HeroServerEvents.java | 3 +- .../reignofnether/hud/ControlGroup.java | 46 +- .../hud/GlobalProductionQueue.java | 77 + .../hud/GlobalProductionQueueRenderer.java | 138 -- .../reignofnether/hud/HudClientEvents.java | 2128 +++-------------- .../reignofnether/hud/MyEditBox.java | 2 + .../hud/PortraitRendererBuilding.java | 121 +- .../hud/PortraitRendererModifiers.java | 164 -- .../hud/PortraitRendererUnit.java | 710 ++---- .../reignofnether/hud/RectZone.java | 24 - .../reignofnether/hud/RegenInfo.java | 108 + .../hud/TextInputClientEvents.java | 46 +- .../reignofnether/hud/TitleClientEvents.java | 11 +- .../reignofnether/hud/TooltipColours.java | 14 +- .../reignofnether/hud/TradeAbilityButton.java | 33 +- .../hud/buttons/AbilityButton.java | 72 +- .../hud/buttons/AbstractUnitItemButton.java | 72 +- .../hud/buttons/ActionButtons.java | 20 +- .../hud/buttons/BooleanButton.java | 46 - .../reignofnether/hud/buttons/Button.java | 233 +- .../hud/buttons/HelperButtons.java | 7 +- .../hud/buttons/IntegerButton.java | 52 - .../hud/buttons/UnitItemInventoryButton.java | 93 +- .../hud/buttons/UnitItemShopButton.java | 34 +- .../hud/custombutton/CustomButton.java | 25 +- .../hud/effecticons/MobEffectIcon.java | 11 +- .../reignofnether/hud/layout/CommandGrid.java | 96 + .../reignofnether/hud/layout/HudGeometry.java | 60 + .../reignofnether/hud/layout/HudLayout.java | 138 ++ .../reignofnether/hud/panels/ButtonCell.java | 317 +++ .../reignofnether/hud/panels/CommandCard.java | 509 ++++ .../reignofnether/hud/panels/HudFrame.java | 214 ++ .../reignofnether/hud/panels/MapZoom.java | 65 + .../hud/panels/MinimapTools.java | 61 + .../hud/panels/SelectionPanel.java | 1105 +++++++++ .../reignofnether/hud/panels/SettingRows.java | 133 ++ .../hud/panels/SettingsMenu.java | 375 +++ .../hud/panels/SpectatorHud.java | 466 ++++ .../hud/panels/TopLeftPanel.java | 481 ++++ .../hud/panels/TopRightPanel.java | 261 ++ .../playerdisplay/AbstractPlayerDisplay.java | 199 +- .../playerdisplay/DiplomacyPlayerDisplay.java | 507 ++-- .../playerdisplay/ObserverPlayerDisplay.java | 205 +- .../PlayerDisplayClientEvents.java | 400 ++-- .../reignofnether/items/ItemClientEvents.java | 104 +- .../reignofnether/items/ItemServerEvents.java | 7 +- .../reignofnether/items/ItemShopMenu.java | 211 +- .../reignofnether/keybinds/Keybindings.java | 45 +- .../keybinds/RtsConflictContext.java | 5 +- .../reignofnether/loading/LoadProgress.java | 40 + .../loading/LoadingScreenClientEvents.java | 711 ++++++ .../matchstart/MatchStartClientEvents.java | 22 +- .../matchstart/MatchStartScreen.java | 1520 +++++++----- .../matchstart/ResultBanner.java | 43 + .../minimap/MapColourServerEvents.java | 113 + .../reignofnether/minimap/MapColours.java | 68 + .../minimap/MapColoursClientboundPacket.java | 81 + .../reignofnether/minimap/MapGrid.java | 29 + .../minimap/MinimapClientEvents.java | 612 ++--- .../minimap/MinimapViewQuadRenderer.java | 4 +- .../minimap/StrategicMapClientEvents.java | 196 ++ .../mixin/ChatComponentMixin.java | 17 +- .../mixin/CreateWorldScreenMixin.java | 37 + .../reignofnether/mixin/ForgeGuiMixin.java | 5 +- .../reignofnether/mixin/MenuButtonMixin.java | 44 + .../reignofnether/mixin/MenuEditBoxMixin.java | 24 + .../mixin/MenuImageButtonMixin.java | 42 + .../reignofnether/mixin/MenuListMixin.java | 48 + .../reignofnether/mixin/MenuSliderMixin.java | 49 + .../mixin/ScreenBackgroundMixin.java | 42 + .../reignofnether/mixin/TabButtonMixin.java | 33 + .../mixin/TabNavigationBarMixin.java | 22 + .../reignofnether/mixin/TitleScreenMixin.java | 220 +- .../reignofnether/orthoview/FaceCulling.java | 45 + .../orthoview/OrthoviewClientEvents.java | 150 +- .../player/PlayerClientEvents.java | 119 +- .../reignofnether/player/PlayerColors.java | 7 +- .../player/PlayerServerEvents.java | 162 +- .../player/PlayerServerboundPacket.java | 46 +- .../player/RTSPlayerScoresCommand.java | 9 +- .../registrars/ClientEventRegistrar.java | 14 +- .../registrars/PacketHandler.java | 7 + .../registrars/ServerEventRegistrar.java | 3 + .../research/ResearchClient.java | 2 + .../resources/IncomeTracker.java | 64 + .../resources/ResourcesClientEvents.java | 61 +- .../reignofnether/rtsmap/RTSMapInfo.java | 8 + .../rtsmap/RTSMapInfoAction.java | 3 +- .../rtsmap/RTSMapInfoClientEvents.java | 7 + .../rtsmap/RTSMapInfoClientboundPacket.java | 1 + .../rtsmap/RTSMapInfoLoader.java | 8 +- .../rtsmap/RTSMapInfoServerEvents.java | 57 +- .../rtsmap/RTSMapInfoServerboundPacket.java | 2 +- .../sandbox/SandboxActionButtons.java | 122 +- .../sandbox/SandboxClientEvents.java | 318 +-- .../reignofnether/sandbox/SandboxPanel.java | 447 ++++ .../scenario/ScenarioClientEvents.java | 66 +- .../reignofnether/scenario/ScenarioMenu.java | 484 ++-- .../scenario/ScenarioServerEvents.java | 15 +- .../startpos/StartPosAction.java | 3 +- .../startpos/StartPosClientEvents.java | 30 +- .../startpos/StartPosServerEvents.java | 32 +- .../startpos/StartPosServerboundPacket.java | 23 +- .../survival/SurvivalServerEvents.java | 26 +- .../TaskSchedulerServerEvents.java | 8 +- .../reignofnether/time/TimeClientEvents.java | 236 +- .../reignofnether/time/TimeServerEvents.java | 15 +- .../reignofnether/time/TimeUtils.java | 7 +- .../tutorial/TutorialClientEvents.java | 29 +- .../tutorial/TutorialRendering.java | 40 +- .../reignofnether/ui/Backdrop.java | 76 + .../solegendary/reignofnether/ui/Clip.java | 21 + .../solegendary/reignofnether/ui/Easing.java | 34 + .../reignofnether/ui/EditorRows.java | 309 +++ .../reignofnether/ui/HudScale.java | 44 + .../solegendary/reignofnether/ui/Icon.java | 47 + .../solegendary/reignofnether/ui/Rect.java | 27 + .../reignofnether/ui/SettingRow.java | 26 + .../solegendary/reignofnether/ui/Text.java | 344 +++ .../solegendary/reignofnether/ui/Theme.java | 317 +++ .../solegendary/reignofnether/ui/Toast.java | 61 + .../solegendary/reignofnether/ui/Tooltip.java | 296 +++ .../reignofnether/unit/UnitChunkTickets.java | 4 + .../reignofnether/unit/UnitClientEvents.java | 42 +- .../reignofnether/unit/UnitServerEvents.java | 23 +- .../reignofnether/unit/interfaces/Unit.java | 3 +- .../UnitSyncWorkerClientBoundPacket.java | 23 +- .../unit/targeting/EntityTargetIndex.java | 13 +- .../unit/units/villagers/VillagerUnit.java | 32 + .../reignofnether/util/MiscUtil.java | 11 + .../reignofnether/util/MyRenderer.java | 113 +- .../reignofnether/util/WorldState.java | 61 + .../reignofnether/util/WorldToScreen.java | 42 + .../worldborder/WorldBorderServerEvents.java | 33 +- .../minecraft/textures/gui/title/discord.png | Bin 17030 -> 0 bytes .../assets/reignofnether/font/big.json | 35 + .../reignofnether/font/pixelify_sans_OFL.txt | 93 + .../reignofnether/font/silkscreen_OFL.txt | 93 + .../assets/reignofnether/font/small.json | 35 + .../assets/reignofnether/lang/da_dk.json | 15 - .../assets/reignofnether/lang/en_us.json | 644 ++++- .../assets/reignofnether/lang/es_ar.json | 76 +- .../assets/reignofnether/lang/es_cl.json | 76 +- .../assets/reignofnether/lang/es_ec.json | 76 +- .../assets/reignofnether/lang/es_es.json | 76 +- .../assets/reignofnether/lang/es_mx.json | 76 +- .../assets/reignofnether/lang/es_uy.json | 76 +- .../assets/reignofnether/lang/es_ve.json | 76 +- .../assets/reignofnether/lang/fa_ir.json | 51 +- .../assets/reignofnether/lang/fr_fr.json | 60 +- .../assets/reignofnether/lang/ko_kr.json | 57 +- .../assets/reignofnether/lang/pl_pl.json | 33 +- .../assets/reignofnether/lang/pt_br.json | 15 - .../assets/reignofnether/lang/ru_ru.json | 78 +- .../assets/reignofnether/lang/tr_tr.json | 55 +- .../assets/reignofnether/lang/uk_ua.json | 27 +- .../assets/reignofnether/lang/vi_vn.json | 57 +- .../assets/reignofnether/lang/zh_cn.json | 78 +- .../assets/reignofnether/lang/zh_tw.json | 58 +- .../reignofnether/textures/font/pixelify.png | Bin 0 -> 9876 bytes .../textures/font/silkscreen.png | Bin 0 -> 1559 bytes .../textures/gui/factions/monsters_blur.png | Bin 0 -> 98274 bytes .../textures/gui/factions/piglins_blur.png | Bin 0 -> 113854 bytes .../textures/gui/factions/villagers_blur.png | Bin 0 -> 119734 bytes .../gui/icons/LICENSE-pixelarticons.txt | 21 + .../textures/gui/icons/book-open.png | Bin 0 -> 154 bytes .../textures/gui/icons/bulletlist.png | Bin 0 -> 127 bytes .../textures/gui/icons/check.png | Bin 0 -> 123 bytes .../textures/gui/icons/close.png | Bin 0 -> 120 bytes .../textures/gui/icons/expand.png | Bin 0 -> 126 bytes .../reignofnether/textures/gui/icons/eye.png | Bin 0 -> 145 bytes .../textures/gui/icons/globe.png | Bin 0 -> 125 bytes .../reignofnether/textures/gui/icons/leaf.png | Bin 0 -> 132 bytes .../reignofnether/textures/gui/icons/lock.png | Bin 0 -> 135 bytes .../reignofnether/textures/gui/icons/map.png | Bin 0 -> 162 bytes .../textures/gui/icons/message.png | Bin 0 -> 140 bytes .../textures/gui/icons/minus.png | Bin 0 -> 100 bytes .../reignofnether/textures/gui/icons/moon.png | Bin 0 -> 161 bytes .../reignofnether/textures/gui/icons/paw.png | Bin 0 -> 119 bytes .../reignofnether/textures/gui/icons/plus.png | Bin 0 -> 118 bytes .../reignofnether/textures/gui/icons/redo.png | Bin 0 -> 144 bytes .../textures/gui/icons/satellite.png | Bin 0 -> 130 bytes .../textures/gui/icons/settings-cog.png | Bin 0 -> 211 bytes .../textures/gui/icons/shrink.png | Bin 0 -> 140 bytes .../textures/gui/icons/shuffle.png | Bin 0 -> 143 bytes .../textures/gui/icons/sliders.png | Bin 0 -> 110 bytes .../reignofnether/textures/gui/icons/undo.png | Bin 0 -> 153 bytes .../textures/gui/icons/unlock.png | Bin 0 -> 140 bytes .../textures/gui/icons/users.png | Bin 0 -> 148 bytes .../textures/gui/icons/zoom-in.png | Bin 0 -> 162 bytes .../textures/gui/icons/zoom-out.png | Bin 0 -> 150 bytes .../textures/gui/menu_accessibility.png | Bin 0 -> 231 bytes .../textures/gui/menu_language.png | Bin 0 -> 339 bytes .../textures/hud/cross_square.png | Bin 1357 -> 0 bytes .../textures/hud/discord_icon.png | Bin 0 -> 162 bytes .../textures/hud/experience_bar_empty.png | Bin 178 -> 0 bytes .../textures/hud/experience_bar_full.png | Bin 1080 -> 0 bytes .../textures/hud/map_background.png | Bin 516 -> 0 bytes .../textures/hud/speech_bubble.png | Bin 241 -> 0 bytes .../textures/hud/title_button.png | Bin 474 -> 0 bytes .../textures/hud/title_button_highlighted.png | Bin 493 -> 0 bytes .../textures/mobheads/villager_farmer.png | Bin 0 -> 558 bytes .../textures/mobheads/villager_hunter.png | Bin 0 -> 479 bytes .../textures/mobheads/villager_lumberjack.png | Bin 0 -> 498 bytes src/main/resources/reignofnether.mixins.json | 10 + .../reignofnether/chat/ChatLogTest.java | 30 + .../hud/layout/CommandGridTest.java | 84 + .../hud/layout/HudLayoutTest.java | 126 + .../reignofnether/util/WorldStateTest.java | 30 + 246 files changed, 14760 insertions(+), 9141 deletions(-) create mode 100644 src/main/java/com/solegendary/reignofnether/chat/ChatLines.java create mode 100644 src/main/java/com/solegendary/reignofnether/chat/ChatLog.java create mode 100644 src/main/java/com/solegendary/reignofnether/chat/ChatPanel.java create mode 100644 src/main/java/com/solegendary/reignofnether/chat/SpectatorFeed.java create mode 100644 src/main/java/com/solegendary/reignofnether/chat/SystemMessage.java delete mode 100644 src/main/java/com/solegendary/reignofnether/config/ReignOfNetherConfigScreen.java delete mode 100644 src/main/java/com/solegendary/reignofnether/config/elements/ConfigCheckbox.java delete mode 100644 src/main/java/com/solegendary/reignofnether/config/elements/ConfigColorButton.java delete mode 100644 src/main/java/com/solegendary/reignofnether/config/elements/Label.java create mode 100644 src/main/java/com/solegendary/reignofnether/hud/GlobalProductionQueue.java delete mode 100644 src/main/java/com/solegendary/reignofnether/hud/GlobalProductionQueueRenderer.java delete mode 100644 src/main/java/com/solegendary/reignofnether/hud/PortraitRendererModifiers.java delete mode 100644 src/main/java/com/solegendary/reignofnether/hud/RectZone.java create mode 100644 src/main/java/com/solegendary/reignofnether/hud/RegenInfo.java delete mode 100644 src/main/java/com/solegendary/reignofnether/hud/buttons/BooleanButton.java delete mode 100644 src/main/java/com/solegendary/reignofnether/hud/buttons/IntegerButton.java create mode 100644 src/main/java/com/solegendary/reignofnether/hud/layout/CommandGrid.java create mode 100644 src/main/java/com/solegendary/reignofnether/hud/layout/HudGeometry.java create mode 100644 src/main/java/com/solegendary/reignofnether/hud/layout/HudLayout.java create mode 100644 src/main/java/com/solegendary/reignofnether/hud/panels/ButtonCell.java create mode 100644 src/main/java/com/solegendary/reignofnether/hud/panels/CommandCard.java create mode 100644 src/main/java/com/solegendary/reignofnether/hud/panels/HudFrame.java create mode 100644 src/main/java/com/solegendary/reignofnether/hud/panels/MapZoom.java create mode 100644 src/main/java/com/solegendary/reignofnether/hud/panels/MinimapTools.java create mode 100644 src/main/java/com/solegendary/reignofnether/hud/panels/SelectionPanel.java create mode 100644 src/main/java/com/solegendary/reignofnether/hud/panels/SettingRows.java create mode 100644 src/main/java/com/solegendary/reignofnether/hud/panels/SettingsMenu.java create mode 100644 src/main/java/com/solegendary/reignofnether/hud/panels/SpectatorHud.java create mode 100644 src/main/java/com/solegendary/reignofnether/hud/panels/TopLeftPanel.java create mode 100644 src/main/java/com/solegendary/reignofnether/hud/panels/TopRightPanel.java create mode 100644 src/main/java/com/solegendary/reignofnether/loading/LoadProgress.java create mode 100644 src/main/java/com/solegendary/reignofnether/loading/LoadingScreenClientEvents.java create mode 100644 src/main/java/com/solegendary/reignofnether/matchstart/ResultBanner.java create mode 100644 src/main/java/com/solegendary/reignofnether/minimap/MapColourServerEvents.java create mode 100644 src/main/java/com/solegendary/reignofnether/minimap/MapColours.java create mode 100644 src/main/java/com/solegendary/reignofnether/minimap/MapColoursClientboundPacket.java create mode 100644 src/main/java/com/solegendary/reignofnether/minimap/MapGrid.java create mode 100644 src/main/java/com/solegendary/reignofnether/minimap/StrategicMapClientEvents.java create mode 100644 src/main/java/com/solegendary/reignofnether/mixin/CreateWorldScreenMixin.java create mode 100644 src/main/java/com/solegendary/reignofnether/mixin/MenuButtonMixin.java create mode 100644 src/main/java/com/solegendary/reignofnether/mixin/MenuEditBoxMixin.java create mode 100644 src/main/java/com/solegendary/reignofnether/mixin/MenuImageButtonMixin.java create mode 100644 src/main/java/com/solegendary/reignofnether/mixin/MenuListMixin.java create mode 100644 src/main/java/com/solegendary/reignofnether/mixin/MenuSliderMixin.java create mode 100644 src/main/java/com/solegendary/reignofnether/mixin/ScreenBackgroundMixin.java create mode 100644 src/main/java/com/solegendary/reignofnether/mixin/TabButtonMixin.java create mode 100644 src/main/java/com/solegendary/reignofnether/mixin/TabNavigationBarMixin.java create mode 100644 src/main/java/com/solegendary/reignofnether/orthoview/FaceCulling.java create mode 100644 src/main/java/com/solegendary/reignofnether/resources/IncomeTracker.java create mode 100644 src/main/java/com/solegendary/reignofnether/sandbox/SandboxPanel.java create mode 100644 src/main/java/com/solegendary/reignofnether/ui/Backdrop.java create mode 100644 src/main/java/com/solegendary/reignofnether/ui/Clip.java create mode 100644 src/main/java/com/solegendary/reignofnether/ui/Easing.java create mode 100644 src/main/java/com/solegendary/reignofnether/ui/EditorRows.java create mode 100644 src/main/java/com/solegendary/reignofnether/ui/HudScale.java create mode 100644 src/main/java/com/solegendary/reignofnether/ui/Icon.java create mode 100644 src/main/java/com/solegendary/reignofnether/ui/Rect.java create mode 100644 src/main/java/com/solegendary/reignofnether/ui/SettingRow.java create mode 100644 src/main/java/com/solegendary/reignofnether/ui/Text.java create mode 100644 src/main/java/com/solegendary/reignofnether/ui/Theme.java create mode 100644 src/main/java/com/solegendary/reignofnether/ui/Toast.java create mode 100644 src/main/java/com/solegendary/reignofnether/ui/Tooltip.java create mode 100644 src/main/java/com/solegendary/reignofnether/util/WorldState.java create mode 100644 src/main/java/com/solegendary/reignofnether/util/WorldToScreen.java delete mode 100644 src/main/resources/assets/minecraft/textures/gui/title/discord.png create mode 100644 src/main/resources/assets/reignofnether/font/big.json create mode 100644 src/main/resources/assets/reignofnether/font/pixelify_sans_OFL.txt create mode 100644 src/main/resources/assets/reignofnether/font/silkscreen_OFL.txt create mode 100644 src/main/resources/assets/reignofnether/font/small.json create mode 100644 src/main/resources/assets/reignofnether/textures/font/pixelify.png create mode 100644 src/main/resources/assets/reignofnether/textures/font/silkscreen.png create mode 100644 src/main/resources/assets/reignofnether/textures/gui/factions/monsters_blur.png create mode 100644 src/main/resources/assets/reignofnether/textures/gui/factions/piglins_blur.png create mode 100644 src/main/resources/assets/reignofnether/textures/gui/factions/villagers_blur.png create mode 100644 src/main/resources/assets/reignofnether/textures/gui/icons/LICENSE-pixelarticons.txt create mode 100644 src/main/resources/assets/reignofnether/textures/gui/icons/book-open.png create mode 100644 src/main/resources/assets/reignofnether/textures/gui/icons/bulletlist.png create mode 100644 src/main/resources/assets/reignofnether/textures/gui/icons/check.png create mode 100644 src/main/resources/assets/reignofnether/textures/gui/icons/close.png create mode 100644 src/main/resources/assets/reignofnether/textures/gui/icons/expand.png create mode 100644 src/main/resources/assets/reignofnether/textures/gui/icons/eye.png create mode 100644 src/main/resources/assets/reignofnether/textures/gui/icons/globe.png create mode 100644 src/main/resources/assets/reignofnether/textures/gui/icons/leaf.png create mode 100644 src/main/resources/assets/reignofnether/textures/gui/icons/lock.png create mode 100644 src/main/resources/assets/reignofnether/textures/gui/icons/map.png create mode 100644 src/main/resources/assets/reignofnether/textures/gui/icons/message.png create mode 100644 src/main/resources/assets/reignofnether/textures/gui/icons/minus.png create mode 100644 src/main/resources/assets/reignofnether/textures/gui/icons/moon.png create mode 100644 src/main/resources/assets/reignofnether/textures/gui/icons/paw.png create mode 100644 src/main/resources/assets/reignofnether/textures/gui/icons/plus.png create mode 100644 src/main/resources/assets/reignofnether/textures/gui/icons/redo.png create mode 100644 src/main/resources/assets/reignofnether/textures/gui/icons/satellite.png create mode 100644 src/main/resources/assets/reignofnether/textures/gui/icons/settings-cog.png create mode 100644 src/main/resources/assets/reignofnether/textures/gui/icons/shrink.png create mode 100644 src/main/resources/assets/reignofnether/textures/gui/icons/shuffle.png create mode 100644 src/main/resources/assets/reignofnether/textures/gui/icons/sliders.png create mode 100644 src/main/resources/assets/reignofnether/textures/gui/icons/undo.png create mode 100644 src/main/resources/assets/reignofnether/textures/gui/icons/unlock.png create mode 100644 src/main/resources/assets/reignofnether/textures/gui/icons/users.png create mode 100644 src/main/resources/assets/reignofnether/textures/gui/icons/zoom-in.png create mode 100644 src/main/resources/assets/reignofnether/textures/gui/icons/zoom-out.png create mode 100644 src/main/resources/assets/reignofnether/textures/gui/menu_accessibility.png create mode 100644 src/main/resources/assets/reignofnether/textures/gui/menu_language.png delete mode 100644 src/main/resources/assets/reignofnether/textures/hud/cross_square.png create mode 100644 src/main/resources/assets/reignofnether/textures/hud/discord_icon.png delete mode 100644 src/main/resources/assets/reignofnether/textures/hud/experience_bar_empty.png delete mode 100644 src/main/resources/assets/reignofnether/textures/hud/experience_bar_full.png delete mode 100644 src/main/resources/assets/reignofnether/textures/hud/map_background.png delete mode 100644 src/main/resources/assets/reignofnether/textures/hud/speech_bubble.png delete mode 100644 src/main/resources/assets/reignofnether/textures/hud/title_button.png delete mode 100644 src/main/resources/assets/reignofnether/textures/hud/title_button_highlighted.png create mode 100644 src/main/resources/assets/reignofnether/textures/mobheads/villager_farmer.png create mode 100644 src/main/resources/assets/reignofnether/textures/mobheads/villager_hunter.png create mode 100644 src/main/resources/assets/reignofnether/textures/mobheads/villager_lumberjack.png create mode 100644 src/test/java/com/solegendary/reignofnether/chat/ChatLogTest.java create mode 100644 src/test/java/com/solegendary/reignofnether/hud/layout/CommandGridTest.java create mode 100644 src/test/java/com/solegendary/reignofnether/hud/layout/HudLayoutTest.java create mode 100644 src/test/java/com/solegendary/reignofnether/util/WorldStateTest.java diff --git a/src/main/java/com/solegendary/reignofnether/ClientModConfigs.java b/src/main/java/com/solegendary/reignofnether/ClientModConfigs.java index 32de04937..d759c4366 100644 --- a/src/main/java/com/solegendary/reignofnether/ClientModConfigs.java +++ b/src/main/java/com/solegendary/reignofnether/ClientModConfigs.java @@ -10,7 +10,7 @@ public class ClientModConfigs { public static void registerClientConfigs(FMLJavaModLoadingContext mlctx) { mlctx.registerConfig(ModConfig.Type.CLIENT, ReignOfNetherClientConfigs.SPEC, - "reignofnether-client-" + ReignOfNether.VERSION_STRING + ".toml"); + "reignofnether-client.toml"); mlctx.registerExtensionPoint( ConfigScreenHandler.ConfigScreenFactory.class, diff --git a/src/main/java/com/solegendary/reignofnether/ClientModEvents.java b/src/main/java/com/solegendary/reignofnether/ClientModEvents.java index 6af4420bc..cbcb058e0 100644 --- a/src/main/java/com/solegendary/reignofnether/ClientModEvents.java +++ b/src/main/java/com/solegendary/reignofnether/ClientModEvents.java @@ -1,6 +1,9 @@ package com.solegendary.reignofnether; +import com.solegendary.reignofnether.blocks.BlockClientEvents; import com.solegendary.reignofnether.blocks.InvisibleBlockRenderer; +import com.solegendary.reignofnether.config.ReignOfNetherClientConfigs; +import com.solegendary.reignofnether.orthoview.OrthoviewClientEvents; import com.solegendary.reignofnether.blocks.SkullTypes; import com.solegendary.reignofnether.building.BuildingPlacement; import com.solegendary.reignofnether.building.BuildingUtils; @@ -181,6 +184,9 @@ public static void registerRenderers(EntityRenderersEvent.RegisterRenderers evt) @SubscribeEvent @OnlyIn(Dist.CLIENT) public static void onClientSetupEvent(FMLClientSetupEvent evt) { + // read on hot render paths, so kept in statics; the toggles write them back + OrthoviewClientEvents.hideLeavesMethod = ReignOfNetherClientConfigs.HIDE_LEAVES.get(); + BlockClientEvents.nightCircleMode = ReignOfNetherClientConfigs.NIGHT_CIRCLES.get(); evt.enqueueWork(() -> { MenuScreens.register(ContainerRegistrar.TOPDOWNGUI_CONTAINER.get(), TopdownGui::new); ItemBlockRenderTypes.setRenderLayer( diff --git a/src/main/java/com/solegendary/reignofnether/alliance/AlliancesClient.java b/src/main/java/com/solegendary/reignofnether/alliance/AlliancesClient.java index 9f727077f..5b12c315e 100644 --- a/src/main/java/com/solegendary/reignofnether/alliance/AlliancesClient.java +++ b/src/main/java/com/solegendary/reignofnether/alliance/AlliancesClient.java @@ -3,17 +3,22 @@ import com.solegendary.reignofnether.gamerules.GameruleClient; import com.solegendary.reignofnether.player.PlayerClientEvents; import com.solegendary.reignofnether.unit.interfaces.Unit; +import com.solegendary.reignofnether.util.WorldState; import net.minecraft.client.Minecraft; import net.minecraft.world.entity.LivingEntity; import java.util.*; public class AlliancesClient { + + static { + WorldState.onClientReset(AlliancesClient::resetAllAlliances); + } private static final Minecraft MC = Minecraft.getInstance(); private static final Map> alliances = new HashMap<>(); - public static final Set inboundPendingAlliances = new HashSet<>(); - public static final Set outboundPendingAlliances = new HashSet<>(); + public static final Set inboundPendingAlliances = WorldState.client(new HashSet<>()); + public static final Set outboundPendingAlliances = WorldState.client(new HashSet<>()); public static final HashSet playersWithAlliedControl = new HashSet<>(); public static boolean sharingAllyControl() { diff --git a/src/main/java/com/solegendary/reignofnether/alliance/AlliancesServerEvents.java b/src/main/java/com/solegendary/reignofnether/alliance/AlliancesServerEvents.java index 8ea3fc5c5..b639f02a9 100644 --- a/src/main/java/com/solegendary/reignofnether/alliance/AlliancesServerEvents.java +++ b/src/main/java/com/solegendary/reignofnether/alliance/AlliancesServerEvents.java @@ -6,17 +6,17 @@ import com.solegendary.reignofnether.scenario.ScenarioServerEvents; import com.solegendary.reignofnether.scenario.ScenarioUtils; import com.solegendary.reignofnether.unit.interfaces.Unit; +import com.solegendary.reignofnether.util.WorldState; import net.minecraft.world.entity.LivingEntity; import net.minecraftforge.event.entity.player.PlayerEvent; -import net.minecraftforge.event.server.ServerStoppedEvent; import net.minecraftforge.eventbus.api.SubscribeEvent; import java.util.*; public class AlliancesServerEvents { - private static final Map> alliances = new HashMap<>(); - public static final Map> pendingAlliances = new HashMap<>(); - public static final HashSet playersWithAlliedControl = new HashSet<>(); + private static final Map> alliances = WorldState.server(new HashMap<>()); + public static final Map> pendingAlliances = WorldState.server(new HashMap<>()); + public static final HashSet playersWithAlliedControl = WorldState.server(new HashSet<>()); public static boolean canControlAlly(String player, LivingEntity entity) { return entity instanceof Unit unit && canControlAlly(player, unit.getOwnerName()); @@ -144,12 +144,6 @@ public static void syncAlliances() { } // statics outlive the world: clear them so the next world opened in this game starts clean - @SubscribeEvent - public static void onServerStopped(ServerStoppedEvent evt) { - alliances.clear(); - pendingAlliances.clear(); - playersWithAlliedControl.clear(); - } @SubscribeEvent public static void onPlayerJoin(PlayerEvent.PlayerLoggedInEvent evt) { diff --git a/src/main/java/com/solegendary/reignofnether/alliance/AllyCommand.java b/src/main/java/com/solegendary/reignofnether/alliance/AllyCommand.java index d54c8bf67..7c2133868 100644 --- a/src/main/java/com/solegendary/reignofnether/alliance/AllyCommand.java +++ b/src/main/java/com/solegendary/reignofnether/alliance/AllyCommand.java @@ -1,5 +1,6 @@ package com.solegendary.reignofnether.alliance; +import com.solegendary.reignofnether.chat.SystemMessage; import com.mojang.brigadier.Command; import com.mojang.brigadier.CommandDispatcher; import com.mojang.brigadier.arguments.BoolArgumentType; @@ -63,26 +64,26 @@ private static int ally(CommandContext context) throws Comma if (context.getSource().getLevel().getGameRules().getRule(GameRuleRegistrar.LOCK_ALLIANCES).get() && (PlayerServerEvents.isRTSPlayer(playerName) || PlayerServerEvents.isRTSPlayer(allyPlayerName))) { - player.sendSystemMessage(Component.translatable("alliance.reignofnether.alliances_lock")); + player.sendSystemMessage(SystemMessage.error(Component.translatable("alliance.reignofnether.alliances_lock"))); return 0; } if (context.getSource().getLevel().getGameRules().getRule(GameRuleRegistrar.COOP_MODE).get() && (PlayerServerEvents.isRTSPlayer(playerName) || PlayerServerEvents.isRTSPlayer(allyPlayerName))) { - player.sendSystemMessage(Component.translatable("alliance.reignofnether.alliances_lock_coop")); + player.sendSystemMessage(SystemMessage.error(Component.translatable("alliance.reignofnether.alliances_lock_coop"))); return 0; } if (player.equals(allyPlayer)) { - player.sendSystemMessage(Component.translatable("alliance.reignofnether.ally_self", playerName)); + player.sendSystemMessage(SystemMessage.error(Component.translatable("alliance.reignofnether.ally_self", playerName))); return 0; } AlliancesServerEvents.pendingAlliances.computeIfAbsent(allyPlayerName, k -> new HashSet<>()).add(playerName); AllianceClientboundPacket.addPendingAlliance(allyPlayerName, playerName); - context.getSource().sendSuccess(()->Component.translatable("alliance.reignofnether.sent_request", allyPlayerName), false); + context.getSource().sendSuccess(()->SystemMessage.info(Component.translatable("alliance.reignofnether.sent_request", allyPlayerName)), false); SoundClientboundPacket.playSoundForPlayer(SoundAction.CHAT, allyPlayerName); - allyPlayer.sendSystemMessage(Component.translatable("alliance.reignofnether.ally_confirm", playerName, playerName)); + allyPlayer.sendSystemMessage(SystemMessage.info(Component.translatable("alliance.reignofnether.ally_confirm", playerName, playerName))); if (PlayerServerEvents.isRTSPlayer(allyPlayerName)) - allyPlayer.sendSystemMessage(Component + allyPlayer.sendSystemMessage(SystemMessage.info(Component .translatable("alliance.reignofnether.accept") // [CLick to accept] .withStyle(Style.EMPTY .withColor(ChatFormatting.GREEN) @@ -96,7 +97,7 @@ private static int ally(CommandContext context) throws Comma .withHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, Component.translatable("alliance.reignofnether.cancel"))) ) ) - ); + )); SoundClientboundPacket.playSoundForPlayer(SoundAction.CHAT, playerName); return Command.SINGLE_SUCCESS; @@ -113,9 +114,9 @@ private static int allyCancelRequest(CommandContext context) } AlliancesServerEvents.pendingAlliances.getOrDefault(playerName, new HashSet<>()).remove(allyPlayerName); AllianceClientboundPacket.cancelPendingAlliance(allyPlayerName, playerName); - context.getSource().sendSuccess(()->Component.translatable("alliance.reignofnether.ally_request_cancelled_self", allyPlayerName), false); + context.getSource().sendSuccess(()->SystemMessage.info(Component.translatable("alliance.reignofnether.ally_request_cancelled_self", allyPlayerName)), false); SoundClientboundPacket.playSoundForPlayer(SoundAction.ENEMY, allyPlayerName); - allyPlayer.sendSystemMessage(Component.translatable("alliance.reignofnether.ally_request_cancelled", playerName)); + allyPlayer.sendSystemMessage(SystemMessage.info(Component.translatable("alliance.reignofnether.ally_request_cancelled", playerName))); SoundClientboundPacket.playSoundForPlayer(SoundAction.ENEMY, playerName); return Command.SINGLE_SUCCESS; @@ -131,19 +132,19 @@ private static int allyConfirm(CommandContext context) throw AlliancesServerEvents.addAlliance(playerName, requesterPlayerName); AlliancesServerEvents.pendingAlliances.getOrDefault(requesterPlayerName, new HashSet<>()).remove(playerName); - context.getSource().sendSuccess(()->Component.translatable("alliance.reignofnether.now_allied", requesterPlayerName), false); + context.getSource().sendSuccess(()->SystemMessage.info(Component.translatable("alliance.reignofnether.now_allied", requesterPlayerName)), false); SoundClientboundPacket.playSoundForPlayer(SoundAction.ALLY, requesterPlayerName); - requesterPlayer.sendSystemMessage(Component.translatable("alliance.reignofnether.ally_accepted", playerName)); + requesterPlayer.sendSystemMessage(SystemMessage.info(Component.translatable("alliance.reignofnether.ally_accepted", playerName))); SoundClientboundPacket.playSoundForPlayer(SoundAction.ALLY, playerName); for (ServerPlayer serverPlayer : PlayerServerEvents.players) { if (!serverPlayer.equals(player) && !serverPlayer.equals(requesterPlayer)) { - serverPlayer.sendSystemMessage(Component.translatable("alliance.reignofnether.now_allied_third_party", playerName, requesterPlayerName)); + serverPlayer.sendSystemMessage(SystemMessage.info(Component.translatable("alliance.reignofnether.now_allied_third_party", playerName, requesterPlayerName))); SoundClientboundPacket.playSoundForPlayer(SoundAction.CHAT, playerName); } } } else { - context.getSource().sendFailure(Component.translatable("alliance.reignofnether.no_request", requesterPlayerName)); + context.getSource().sendFailure(SystemMessage.error(Component.translatable("alliance.reignofnether.no_request", requesterPlayerName))); } return Command.SINGLE_SUCCESS; } @@ -156,29 +157,29 @@ private static int disband(CommandContext context) throws Co if (context.getSource().getLevel().getGameRules().getRule(GameRuleRegistrar.LOCK_ALLIANCES).get() && (PlayerServerEvents.isRTSPlayer(playerName) || PlayerServerEvents.isRTSPlayer(allyPlayerName))) { - player.sendSystemMessage(Component.translatable("alliance.reignofnether.alliances_lock")); + player.sendSystemMessage(SystemMessage.error(Component.translatable("alliance.reignofnether.alliances_lock"))); return 0; } if (context.getSource().getLevel().getGameRules().getRule(GameRuleRegistrar.COOP_MODE).get() && (PlayerServerEvents.isRTSPlayer(playerName) || PlayerServerEvents.isRTSPlayer(allyPlayerName))) { - player.sendSystemMessage(Component.translatable("alliance.reignofnether.alliances_lock_coop")); + player.sendSystemMessage(SystemMessage.error(Component.translatable("alliance.reignofnether.alliances_lock_coop"))); return 0; } if (player.equals(allyPlayer)) { - context.getSource().sendFailure(Component.translatable("alliance.reignofnether.disband_self")); + context.getSource().sendFailure(SystemMessage.error(Component.translatable("alliance.reignofnether.disband_self"))); return 0; } AlliancesServerEvents.removeAlliance(playerName, allyPlayerName); - player.sendSystemMessage(Component.translatable("alliance.reignofnether.disbanded", allyPlayerName)); + player.sendSystemMessage(SystemMessage.info(Component.translatable("alliance.reignofnether.disbanded", allyPlayerName))); SoundClientboundPacket.playSoundForPlayer(SoundAction.ENEMY, playerName); - allyPlayer.sendSystemMessage(Component.translatable("alliance.reignofnether.disbanded", playerName)); + allyPlayer.sendSystemMessage(SystemMessage.info(Component.translatable("alliance.reignofnether.disbanded", playerName))); SoundClientboundPacket.playSoundForPlayer(SoundAction.ENEMY, allyPlayerName); for (ServerPlayer serverPlayer : PlayerServerEvents.players) { if (!serverPlayer.equals(player) && !serverPlayer.equals(allyPlayer)) { - serverPlayer.sendSystemMessage(Component.translatable("alliance.reignofnether.disbanded_third_party", playerName, allyPlayerName)); + serverPlayer.sendSystemMessage(SystemMessage.info(Component.translatable("alliance.reignofnether.disbanded_third_party", playerName, allyPlayerName))); SoundClientboundPacket.playSoundForPlayer(SoundAction.CHAT, playerName); } } @@ -190,7 +191,7 @@ private static int getAlliedControl(CommandContext context) String playerName = player.getName().getString(); boolean value = AlliancesServerEvents.playersWithAlliedControl.contains(playerName); String msgKey = value ? "alliance.reignofnether.ally_control_enabled" : "alliance.reignofnether.ally_control_disabled"; - context.getSource().sendSuccess(()->Component.translatable(msgKey, playerName), false); + context.getSource().sendSuccess(()->SystemMessage.info(Component.translatable(msgKey, playerName)), false); return Command.SINGLE_SUCCESS; } @@ -206,11 +207,11 @@ private static int setAlliedControl(CommandContext context) AlliancesServerEvents.playersWithAlliedControl.remove(playerName); AllianceClientboundPacket.setAllyControl(playerName, value); - context.getSource().sendSuccess(()->Component.translatable(msgKey, playerName), false); + context.getSource().sendSuccess(()->SystemMessage.info(Component.translatable(msgKey, playerName)), false); SoundClientboundPacket.playSoundForPlayer(SoundAction.CHAT, playerName); for (String allyPlayerName : AlliancesServerEvents.getAllAllies(playerName)) { - PlayerServerEvents.sendMessageToPlayerNoNewLines(allyPlayerName, msgKey, false, playerName); + PlayerServerEvents.sendMessageToPlayer(allyPlayerName, msgKey, false, playerName); SoundClientboundPacket.playSoundForPlayer(SoundAction.CHAT, allyPlayerName); } return Command.SINGLE_SUCCESS; diff --git a/src/main/java/com/solegendary/reignofnether/building/BuildingClientEvents.java b/src/main/java/com/solegendary/reignofnether/building/BuildingClientEvents.java index 1600bffc7..d942c3a25 100644 --- a/src/main/java/com/solegendary/reignofnether/building/BuildingClientEvents.java +++ b/src/main/java/com/solegendary/reignofnether/building/BuildingClientEvents.java @@ -1,6 +1,8 @@ package com.solegendary.reignofnether.building; +import com.solegendary.reignofnether.hud.buttons.HelperButtons; import com.mojang.blaze3d.platform.NativeImage; +import com.solegendary.reignofnether.player.PlayerClientEvents; import com.mojang.blaze3d.systems.RenderSystem; import com.mojang.blaze3d.vertex.PoseStack; import com.solegendary.reignofnether.ReignOfNether; @@ -16,6 +18,7 @@ import com.solegendary.reignofnether.building.custombuilding.CustomBuilding; import com.solegendary.reignofnether.building.production.ActiveProduction; import com.solegendary.reignofnether.cursor.CursorClientEvents; +import com.solegendary.reignofnether.faction.Factions; import com.solegendary.reignofnether.fogofwar.FogOfWarClientEvents; import com.solegendary.reignofnether.gamerules.GameruleClient; import com.solegendary.reignofnether.hud.HudClientEvents; @@ -37,6 +40,7 @@ import com.solegendary.reignofnether.unit.interfaces.WorkerUnit; import com.solegendary.reignofnether.util.MiscUtil; import com.solegendary.reignofnether.util.MyRenderer; +import com.solegendary.reignofnether.util.WorldState; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.screens.inventory.BeaconScreen; import net.minecraft.client.gui.screens.inventory.ContainerScreen; @@ -73,10 +77,14 @@ import static com.solegendary.reignofnether.unit.UnitClientEvents.getSelectedUnits; public class BuildingClientEvents { + static { + WorldState.onClientReset(() -> setBuildingToPlace(null)); + } + static final Minecraft MC = Minecraft.getInstance(); public static int getTotalPopulationSupply(String playerName) { - if (ResearchClient.hasCheat("foodforthought")) { + if (ResearchClient.hasCheat("foodforthought") || PlayerClientEvents.getPlayerFaction(playerName) == Factions.NONE) { return GameruleClient.maxPopulation; } @@ -90,7 +98,7 @@ public static int getTotalPopulationSupply(String playerName) { } // clientside buildings used for tracking position (for cursor selection) - private static final ArrayList buildings = new ArrayList<>(); + private static final ArrayList buildings = WorldState.client(new ArrayList<>()); private static final ArrayList selectedBuildings = new ArrayList<>(); private static Building buildingToPlace = null; private static Building lastBuildingToPlace = null; @@ -478,7 +486,7 @@ public static boolean isBridgeDiagonal() { @SubscribeEvent public static void onMouseScroll(ScreenEvent.MouseScrolled.Post evt) { - if (buildingToPlace != null) { + if (buildingToPlace != null && !Keybindings.altMod.isDown()) { // Alt + wheel zooms instead if (buildingToPlace instanceof AbstractBridge bridge) { bridgePlaceState += evt.getScrollDelta() > 0 ? 1 : -1; if (bridgePlaceState < 0) { @@ -741,7 +749,9 @@ public static void onButtonPress(ScreenEvent.KeyPressed.Pre evt) { if (building != null && building.getBuilding().capturable && !isSandboxPlayer) { HudClientEvents.showTemporaryMessage(I18n.get("server.reignofnether.cannot_delete_capturable")); } else if (building != null && - ((building.isBuilt && getPlayerToBuildingRelationship(building) == Relationship.OWNED) || isSandboxPlayer)) { + // unbuilt: cancel construction, under the same rule as the card's Cancel button (B) + (((building.isBuilt || !HelperButtons.buildingCancelButton.isHidden.get()) + && getPlayerToBuildingRelationship(building) == Relationship.OWNED) || isSandboxPlayer)) { HudClientEvents.hudSelectedPlacement = null; BuildingServerboundPacket.cancelBuilding(building.minCorner, MC.player.getName().getString()); } @@ -787,7 +797,12 @@ public static void onClientTick(TickEvent.ClientTickEvent evt) { // cleanup destroyed buildings selectedBuildings.removeIf(BuildingPlacement::shouldBeDestroyed); - buildings.removeIf(BuildingPlacement::shouldBeDestroyed); + buildings.removeIf(b -> { + if (!b.shouldBeDestroyed()) + return false; + onLost(b); + return true; + }); } } @@ -965,10 +980,26 @@ public static void syncBeacon(UnitAction action, BlockPos beaconPos, boolean act } public static void removeBuilding(BlockPos bp) { - buildings.removeIf(b -> b.originPos.equals(bp)); + buildings.removeIf(b -> { + if (!b.originPos.equals(bp)) + return false; + onLost(b); + return true; + }); BuildingClientEvents.clearSelectedBuildings(); } + /** Losing your last capital: a tip in chat that surrender is in the pause menu. */ + private static void onLost(BuildingPlacement b) { + if (!b.isCapitol || !b.isBuilt || MC.player == null || !PlayerClientEvents.isRTSPlayer() + || !b.ownerName.equals(MC.player.getName().getString())) + return; + boolean another = buildings.stream().anyMatch(o -> o != b && o.isCapitol && o.ownerName.equals(b.ownerName) && !o.shouldBeDestroyed()); + if (!another) + MC.gui.getChat().addMessage(com.solegendary.reignofnether.chat.SystemMessage.important( + net.minecraft.network.chat.Component.translatable("hud.reignofnether.capital_lost_tip"))); + } + public static void removeFogQueuedBuilding(BlockPos bp) { for (LivingEntity le : UnitClientEvents.getAllUnits()) { if (le instanceof WorkerUnit workerUnit) { diff --git a/src/main/java/com/solegendary/reignofnether/building/BuildingPlaceButton.java b/src/main/java/com/solegendary/reignofnether/building/BuildingPlaceButton.java index 57996889b..637136ad4 100644 --- a/src/main/java/com/solegendary/reignofnether/building/BuildingPlaceButton.java +++ b/src/main/java/com/solegendary/reignofnether/building/BuildingPlaceButton.java @@ -9,11 +9,14 @@ import java.util.function.Supplier; public class BuildingPlaceButton extends Button { + public final Building building; + public BuildingPlaceButton(String name, ResourceLocation rl, Keybinding hotkey, Supplier isSelected, Supplier isHidden, Supplier isEnabled, List tooltipLines, Building building) { // generate x/y based on given position (starting at 0 which is bottom left 1 row above generic action buttons) super(name, Button.itemIconSize, rl, hotkey, isSelected, isHidden, isEnabled, () -> BuildingClientEvents.setBuildingToPlace(building), null, tooltipLines); + this.building = building; } } diff --git a/src/main/java/com/solegendary/reignofnether/building/BuildingPlacement.java b/src/main/java/com/solegendary/reignofnether/building/BuildingPlacement.java index 6b6c2a380..b3baaa234 100644 --- a/src/main/java/com/solegendary/reignofnether/building/BuildingPlacement.java +++ b/src/main/java/com/solegendary/reignofnether/building/BuildingPlacement.java @@ -896,6 +896,7 @@ public void onBuilt() { if (rtsPlayer != null) rtsPlayer.scores.addToScore(RTSPlayerScoresEnum.TOTAL_BUILDINGS_CONSTRUCTED); } else { + com.solegendary.reignofnether.chat.SpectatorFeed.built(ownerName, com.solegendary.reignofnether.hud.panels.SelectionPanel.buildingName(this)); TutorialClientEvents.updateStage(); if (this.isCapitol && !SandboxClientEvents.isSandboxPlayer() && getTotalCompletedBuildingsOwned(this.level.isClientSide(), ownerName) == 1) diff --git a/src/main/java/com/solegendary/reignofnether/building/BuildingServerEvents.java b/src/main/java/com/solegendary/reignofnether/building/BuildingServerEvents.java index c1d8dcc3e..77e0c054a 100644 --- a/src/main/java/com/solegendary/reignofnether/building/BuildingServerEvents.java +++ b/src/main/java/com/solegendary/reignofnether/building/BuildingServerEvents.java @@ -667,7 +667,7 @@ public static void cancelBuilding(BuildingPlacement building, String playerName) } public static int getTotalPopulationSupply(String ownerName) { - if (ResearchServerEvents.playerHasCheat(ownerName, "foodforthought")) { + if (ResearchServerEvents.playerHasCheat(ownerName, "foodforthought") || SandboxServer.isSandboxPlayer(ownerName)) { return UnitServerEvents.maxPopulation; } diff --git a/src/main/java/com/solegendary/reignofnether/building/buildings/placements/BeaconPlacement.java b/src/main/java/com/solegendary/reignofnether/building/buildings/placements/BeaconPlacement.java index 71681f4f8..e465e31ff 100644 --- a/src/main/java/com/solegendary/reignofnether/building/buildings/placements/BeaconPlacement.java +++ b/src/main/java/com/solegendary/reignofnether/building/buildings/placements/BeaconPlacement.java @@ -198,7 +198,6 @@ public void onBuilt() { public void sendWarning(String msg) { if (!level.isClientSide) { - PlayerServerEvents.sendMessageToAllPlayersNoNewlines(""); BeaconPlacement beacon = BuildingUtils.getBeacon(level.isClientSide); if (beacon != null && msg.equals("upgraded_warning")) { String upgradeName = ""; @@ -208,17 +207,16 @@ public void sendWarning(String msg) { else if (beacon.getUpgradeLevel() == 4) upgradeName = Component.translatable("buildings.reignofnether.beacon.upgrade.beacon_level4").getString(); else if (beacon.getUpgradeLevel() == 5) upgradeName = Component.translatable("buildings.reignofnether.beacon.upgrade.beacon_level5").getString(); - PlayerServerEvents.sendMessageToAllPlayersNoNewlines("buildings.reignofnether.beacon.upgrade_warning", + PlayerServerEvents.sendMessageToAllPlayers("buildings.reignofnether.beacon.upgrade_warning", true, ownerName, upgradeName, beacon.getUpgradeLevel(), Beacon.MAX_UPGRADE_LEVEL); } else { - PlayerServerEvents.sendMessageToAllPlayersNoNewlines("buildings.reignofnether.beacon." + msg, + PlayerServerEvents.sendMessageToAllPlayers("buildings.reignofnether.beacon." + msg, true, ownerName); } if (beacon != null && beacon.getUpgradeLevel() >= Beacon.MAX_UPGRADE_LEVEL && !msg.equals("destroy_warning")) { - PlayerServerEvents.sendMessageToAllPlayersNoNewlines("buildings.reignofnether.beacon.time_to_win", + PlayerServerEvents.sendMessageToAllPlayers("buildings.reignofnether.beacon.time_to_win", false, ownerName, PlayerServerEvents.getBeaconWinTime(ownerName)); } - PlayerServerEvents.sendMessageToAllPlayersNoNewlines(""); if (SurvivalServerEvents.isEnabled() && !msg.equals("destroy_warning")) SoundClientboundPacket.playSoundForAllPlayers(SoundAction.ALLY); else diff --git a/src/main/java/com/solegendary/reignofnether/building/custombuilding/CustomBuildingClientEvents.java b/src/main/java/com/solegendary/reignofnether/building/custombuilding/CustomBuildingClientEvents.java index 861738649..1626f33c2 100644 --- a/src/main/java/com/solegendary/reignofnether/building/custombuilding/CustomBuildingClientEvents.java +++ b/src/main/java/com/solegendary/reignofnether/building/custombuilding/CustomBuildingClientEvents.java @@ -1,13 +1,15 @@ package com.solegendary.reignofnether.building.custombuilding; +import com.solegendary.reignofnether.chat.SystemMessage; import com.solegendary.reignofnether.blocks.RTSStructureBlockEntity; import com.solegendary.reignofnether.building.Building; import com.solegendary.reignofnether.building.BuildingBlock; import com.solegendary.reignofnether.building.BuildingBlockData; import com.solegendary.reignofnether.guiscreen.TopdownGui; -import com.solegendary.reignofnether.hud.buttons.Button; -import com.solegendary.reignofnether.hud.RectZone; +import com.solegendary.reignofnether.hud.panels.HudFrame; +import com.solegendary.reignofnether.ui.EditorRows; import com.solegendary.reignofnether.util.MyRenderer; +import com.solegendary.reignofnether.util.WorldState; import net.minecraft.client.Minecraft; import net.minecraft.core.BlockPos; import net.minecraft.core.Vec3i; @@ -22,7 +24,6 @@ import net.minecraftforge.client.event.RenderLevelStageEvent; import net.minecraftforge.client.event.ScreenEvent; import net.minecraftforge.eventbus.api.SubscribeEvent; -import org.lwjgl.glfw.GLFW; import java.util.ArrayList; @@ -31,6 +32,10 @@ public class CustomBuildingClientEvents { + static { + WorldState.onClientReset(() -> setCustomBuildingToEdit(null)); + } + // since every custom building has a different structure, we need to maintain a list of them here public static final ArrayList customBuildings = new ArrayList<>(); @@ -39,8 +44,7 @@ public class CustomBuildingClientEvents { private static final Minecraft MC = Minecraft.getInstance(); private static CustomBuilding customBuildingToEdit = null; - private static final ArrayList