From 9fff4dbb5d6e57294aa2a446123a5e4bd6eabd39 Mon Sep 17 00:00:00 2001 From: Player Name Date: Sat, 1 Feb 2025 13:02:22 +0000 Subject: [PATCH] Implemented spade pickup in the Rimmington mine Rewrote the permadeath code to more thoroughly wipe HCIM when they die HCIM permadeath code destroys items dropped on death Cleaned up redundant blast furnace player save code --- .../rimmington/handler/RimmingtonListeners.kt | 29 +++++ Server/src/main/core/api/utils/Permadeath.kt | 102 ++++++++++++++++-- .../core/game/node/entity/player/Player.java | 17 +-- .../player/info/login/PlayerSaveParser.kt | 3 - .../entity/player/info/login/PlayerSaver.kt | 10 -- .../entity/player/link/BankPinManager.java | 14 ++- .../main/core/game/node/item/GroundItem.java | 4 + .../system/command/sets/MiscCommandSet.kt | 2 +- 8 files changed, 138 insertions(+), 43 deletions(-) create mode 100644 Server/src/main/content/region/asgarnia/rimmington/handler/RimmingtonListeners.kt diff --git a/Server/src/main/content/region/asgarnia/rimmington/handler/RimmingtonListeners.kt b/Server/src/main/content/region/asgarnia/rimmington/handler/RimmingtonListeners.kt new file mode 100644 index 000000000..5dc727594 --- /dev/null +++ b/Server/src/main/content/region/asgarnia/rimmington/handler/RimmingtonListeners.kt @@ -0,0 +1,29 @@ +package content.region.asgarnia.rimmington.handler + +import core.api.* +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.node.item.Item +import core.game.node.scenery.Scenery +import org.rs09.consts.Items +import org.rs09.consts.Sounds + +/** + * @author Player Name + */ + +class RimmingtonListeners : InteractionListener { + override fun defineListeners() { + on(9662, IntType.SCENERY, "take") { player, node -> + if (!hasSpaceFor(player, Item(Items.SPADE_952))) { + sendMessage(player, "You don't have enough inventory space to hold that item.") + return@on true + } + animate(player, 535) + playAudio(player, Sounds.PICK2_2582) + addItem(player, Items.SPADE_952) + replaceScenery(node as Scenery, 0, 50) + return@on true + } + } +} diff --git a/Server/src/main/core/api/utils/Permadeath.kt b/Server/src/main/core/api/utils/Permadeath.kt index 0c0ac1e17..c7e5069f4 100644 --- a/Server/src/main/core/api/utils/Permadeath.kt +++ b/Server/src/main/core/api/utils/Permadeath.kt @@ -1,32 +1,72 @@ -package core.api.utils.Permadeath +package core.api.utils -import core.api.* +import content.global.skill.construction.HouseLocation +import content.minigame.blastfurnace.BFPlayerState +import content.minigame.blastfurnace.BlastFurnace +import core.api.isUsingSecondaryBankAccount +import core.api.teleport +import core.api.toggleBankAccount import core.game.node.entity.player.Player import core.game.node.entity.player.VarpManager import core.game.node.entity.player.info.login.PlayerSaver import core.game.node.entity.player.link.IronmanMode import core.game.node.entity.player.link.SavedData +import core.game.node.entity.player.link.SpellBookManager import core.game.node.entity.player.link.diary.DiaryType import core.game.node.entity.player.link.quest.QuestRepository import core.game.node.entity.skill.Skills +import core.game.node.item.GroundItem +import core.game.node.item.GroundItemManager import core.game.world.map.Location +import java.util.ArrayList fun permadeath(target: Player) { teleport(target, Location.create(3094, 3107, 0)) - target.equipment.clear() + + // Core target.inventory.clear() + target.bank.clear() + target.bankSecondary.clear() + for (i in target.bankPrimary.tabStartSlot.indices) { + target.bankPrimary.tabStartSlot[i] = 0 + } + for (i in target.bankSecondary.tabStartSlot.indices) { + target.bankSecondary.tabStartSlot[i] = 0 + } if (isUsingSecondaryBankAccount(target)) { toggleBankAccount(target) } - target.bank.clear() - target.bankSecondary.clear() - target.skills = Skills(target) - target.clearAttributes() - target.savedData = SavedData(target) - target.questRepository = QuestRepository(target) + target.equipment.clear() target.varpManager = VarpManager(target) target.varpMap.clear() target.saveVarp.clear() + target.timers.clearTimers() + + // Skills + target.skills = Skills(target) + + // Settings can be kept + + // Quests + target.questRepository = QuestRepository(target) + + // Appearance doesn't matter because you're going to tutorial island anyway + + // Spellbook + target.spellBookManager.setSpellBook(SpellBookManager.SpellBook.MODERN) + + // Saved data + target.savedData = SavedData(target) + + // Autocast + target.properties.autocastSpell = null + + // Player monitor is a no-op + + // Music player + target.musicPlayer.clearUnlocked() + + // Familiar manager if (target.familiarManager.hasFamiliar()) { target.familiarManager.dismiss() } @@ -34,6 +74,14 @@ fun permadeath(target: Player) { for (key in petKeys) { target.familiarManager.removeDetails(key) } + + // Bank pin data + target.bankPinManager.doCancelPin() + + // House data + target.houseManager.createNewHouseAt(HouseLocation.NOWHERE) + + // Achievements for (type in DiaryType.values()) { val diary = target.achievementDiaryManager.getDiary(type) for (level in 0 until diary.levelStarted.size) { @@ -42,8 +90,42 @@ fun permadeath(target: Player) { } } } - target.musicPlayer.clearUnlocked() + + // Ironman data target.ironmanManager.mode = IronmanMode.NONE + + // Emote data + target.emoteManager.emotes.clear() + + // Stat manager is a no-op + + // Attributes + target.clearAttributes() + + // Pouches + for (pouch in target.pouchManager.pouches.values) { + pouch.container.clear() + pouch.currentCap = pouch.capacity + pouch.charges = pouch.maxCharges + pouch.remakeContainer() + } + + // Destroy any dropped items to prevent droptrading to yourself after death + val droppedItems = ArrayList(); + for (item in GroundItemManager.getItems()) { + if (item.dropperUid == target.details.uid) { + droppedItems.add(item) + } + } + for (item in droppedItems) { + GroundItemManager.destroy(item) + } + + // grep -R savePlayer: jobs, treasure trails, brawling gloves, slayer manager, barcrawl, ge history will simply not get saved if we don't run the hooks + // Only the Blast Furnace needs to be reset explicitly + BlastFurnace.playerStates[target.details.uid] = BFPlayerState(target) + + // Sayonara PlayerSaver(target).save() target.clear() } diff --git a/Server/src/main/core/game/node/entity/player/Player.java b/Server/src/main/core/game/node/entity/player/Player.java index a23d472c7..0fb8f6110 100644 --- a/Server/src/main/core/game/node/entity/player/Player.java +++ b/Server/src/main/core/game/node/entity/player/Player.java @@ -89,7 +89,7 @@ import java.util.*; import java.util.concurrent.TimeUnit; import static core.api.ContentAPIKt.*; -import static core.api.utils.Permadeath.PermadeathKt.permadeath; +import static core.api.utils.PermadeathKt.permadeath; import static core.game.system.command.sets.StatAttributeKeysKt.STATS_BASE; import static core.game.system.command.sets.StatAttributeKeysKt.STATS_DEATHS; import static core.tools.GlobalsKt.colorize; @@ -155,21 +155,6 @@ public class Player extends Entity { */ public boolean useSecondaryBank = false; - /** - * The Blast Furnace Coal Container. - */ - public final Container blastCoal = new Container(225, ContainerType.NEVER_STACK); - - /** - * The Blast Furnace Ore Container. - */ - public final Container blastOre = new Container(28, ContainerType.NEVER_STACK); - - /** - * The Blast Furnace Bars Container. - */ - public final Container blastBars = new Container(28, ContainerType.NEVER_STACK); - /** * The packet dispatcher. */ diff --git a/Server/src/main/core/game/node/entity/player/info/login/PlayerSaveParser.kt b/Server/src/main/core/game/node/entity/player/info/login/PlayerSaveParser.kt index d9b0105f0..64e4a80e6 100644 --- a/Server/src/main/core/game/node/entity/player/info/login/PlayerSaveParser.kt +++ b/Server/src/main/core/game/node/entity/player/info/login/PlayerSaveParser.kt @@ -327,9 +327,6 @@ class PlayerSaveParser(val player: Player) { player.bankPrimary.parse(bank) player.bankSecondary.parse(bankSecondary) player.equipment.parse(equipment) - bBars?.let{player.blastBars.parse(it)} - bOre?.let{player.blastOre.parse(bOre)} - bCoal?.let{player.blastCoal.parse(bCoal)} player.location = JSONUtils.parseLocation(location) if (varpData != null) { diff --git a/Server/src/main/core/game/node/entity/player/info/login/PlayerSaver.kt b/Server/src/main/core/game/node/entity/player/info/login/PlayerSaver.kt index 7d5318921..8b34bebb4 100644 --- a/Server/src/main/core/game/node/entity/player/info/login/PlayerSaver.kt +++ b/Server/src/main/core/game/node/entity/player/info/login/PlayerSaver.kt @@ -19,7 +19,6 @@ import org.json.simple.JSONObject import java.io.File import java.io.FileWriter import java.io.IOException -import java.lang.Math.ceil import javax.script.ScriptEngineManager import java.util.* @@ -613,15 +612,6 @@ class PlayerSaver (val player: Player){ val bankSecondary = saveContainer(player.bankSecondary) coreData.put("bankSecondary",bankSecondary) - val bBars = saveContainer(player.blastBars) - coreData.put("blastBars",bBars) - - val bOre = saveContainer(player.blastOre) - coreData.put("blastOre",bOre) - - val bCoal = saveContainer(player.blastCoal) - coreData.put("blastCoal",bCoal) - val bankTabs = JSONArray() for(i in player.bankPrimary.tabStartSlot.indices){ val tab = JSONObject() diff --git a/Server/src/main/core/game/node/entity/player/link/BankPinManager.java b/Server/src/main/core/game/node/entity/player/link/BankPinManager.java index b4dc61d26..321b5f8bf 100644 --- a/Server/src/main/core/game/node/entity/player/link/BankPinManager.java +++ b/Server/src/main/core/game/node/entity/player/link/BankPinManager.java @@ -470,17 +470,25 @@ public class BankPinManager { } /** - * Cancels the pin. + * Cancels the pin and shows the correct interface. */ public void cancelPin(String... messages) { + doCancelPin(); + playAudio(player, Sounds.PIN_CANCEL_1042); + openSettings(messages); + } + + /** + * Actually cancels the pin. + */ + public void doCancelPin() { status = PinStatus.NO_PIN; pendingDelay = -1; pin = null; unlocked = false; - playAudio(player, Sounds.PIN_CANCEL_1042); - openSettings(messages); } + /** * Checks if the pin is an easy guess. * @return {@code True} if so. diff --git a/Server/src/main/core/game/node/item/GroundItem.java b/Server/src/main/core/game/node/item/GroundItem.java index dfdfe92f1..ba5c4e272 100644 --- a/Server/src/main/core/game/node/item/GroundItem.java +++ b/Server/src/main/core/game/node/item/GroundItem.java @@ -202,9 +202,13 @@ public class GroundItem extends Item { this.removed = removed; } + /** + * Gets the dropper uid. + */ public int getDropperUid() { return dropperUid; } + @Override public String toString() { return "GroundItem [dropper=" + (dropper != null ? dropper.getUsername() : dropper) + ", ticks=" + ticks + ", decayTime=" + decayTime + ", remainPrivate=" + remainPrivate + ", removed=" + removed + "]"; diff --git a/Server/src/main/core/game/system/command/sets/MiscCommandSet.kt b/Server/src/main/core/game/system/command/sets/MiscCommandSet.kt index 6911212e1..0fec9ec16 100644 --- a/Server/src/main/core/game/system/command/sets/MiscCommandSet.kt +++ b/Server/src/main/core/game/system/command/sets/MiscCommandSet.kt @@ -6,7 +6,7 @@ import content.minigame.fishingtrawler.TrawlerLoot import content.region.misthalin.draynor.quest.anma.AnmaCutscene import core.ServerConstants import core.api.* -import core.api.utils.Permadeath.permadeath +import core.api.utils.permadeath import core.cache.def.impl.NPCDefinition import core.cache.def.impl.SceneryDefinition import core.cache.def.impl.VarbitDefinition