From 2ad90e9ed86869a2b1210d90a9240c74927778bf Mon Sep 17 00:00:00 2001 From: randy Date: Thu, 14 Aug 2025 16:47:56 -0600 Subject: [PATCH] Fixed Combiniation rune consumption and rebalanced rune satchel Combination runes have been fixed. A spell using 1 air and 1 earth rune will now only use 1 dust rune instead of 2. Rune satchel has been changed. Instead of allowing only catalytic runes, it now allows all runes but only has 6 slots. In addition, combination runes can be used from the satchel. --- Server/data/configs/item_configs.json | 2 +- .../handlers/item/SnowscapeSatchelListener.kt | 7 +-- .../content/global/skill/magic/SpellUtils.kt | 42 ++++++++++++++++- .../node/entity/combat/spell/MagicSpell.java | 46 +++++++++++++++++++ .../core/game/node/entity/player/Player.java | 2 +- 5 files changed, 89 insertions(+), 10 deletions(-) diff --git a/Server/data/configs/item_configs.json b/Server/data/configs/item_configs.json index 6e08c6501..982b254a1 100644 --- a/Server/data/configs/item_configs.json +++ b/Server/data/configs/item_configs.json @@ -93970,7 +93970,7 @@ "equipment_slot": "5" }, { - "examine": "I can keep my catalytic runes in here.", + "examine": "I can keep my runes in here.", "durability": null, "name": "Rune satchel", "weight": "0.1", diff --git a/Server/src/main/content/global/handlers/item/SnowscapeSatchelListener.kt b/Server/src/main/content/global/handlers/item/SnowscapeSatchelListener.kt index 9f8709b6c..872c94341 100755 --- a/Server/src/main/content/global/handlers/item/SnowscapeSatchelListener.kt +++ b/Server/src/main/content/global/handlers/item/SnowscapeSatchelListener.kt @@ -37,10 +37,6 @@ class SnowscapeSatchelListener : InteractionListener { val runeSatchelId = 10882 val satchelIds = intArrayOf(plainSatchelId,greenSatchelId,redSatchelId,blackSatchelId,goldSatchelId,runeSatchelId) - //val runeSatchelAllowed = intArrayOf(558,559,564,562,9075,561,563,560,565,566) - //val runesForbidden = intArrayOf(556,555,557,554,4695,4696,4698,4697,4694,4699) - - @@ -103,7 +99,6 @@ class SnowscapeSatchelListener : InteractionListener { // This is called by BurdenInterfacePlugin.java when the player interacts with the familiar interface and the "openSatchel" attribute exists fun satchelInterfaceAction(player: Player, component: Component, opcode: Int, button: Int, slot: Int, itemId: Int) { - //player.sendMessage("Button:" + button.toString() + ". Opcode:" + opcode.toString()) val satchelId = getAttribute(player, "openSatchel", 0) val withdraw = component.getId() == 671 val container = if (withdraw) getSatchel(player, satchelId) else player.getInventory() @@ -142,7 +137,7 @@ class SnowscapeSatchelListener : InteractionListener { redSatchelId -> return itemId in intArrayOf(*(12158..12168).toList().toIntArray()) || Item(itemId).getName().equals("Clue scroll") blackSatchelId -> return itemId in intArrayOf(995) goldSatchelId -> return itemId in intArrayOf(436,438,440,442,444,446,447,449,451,453,668,2892,2349,2351,2353,2355,2357,2359,2361,2363,2365,1601,1603,1605,1607,1609,1611,1613,1615,1617,1619,1621,1623,1625,1627,1629,1631,6571,6573) - runeSatchelId -> return itemId in intArrayOf(558,559,564,562,9075,561,563,560,565,566) || (getAttribute(player,"snowscape:boostedmode",false) && itemId in intArrayOf(556,555,557,554,4694,4695,4696,4697,4698,4699)) + runeSatchelId -> return itemId in intArrayOf(556,555,557,554,558,559,564,562,9075,561,563,560,565,566,4694,4695,4696,4697,4698,4699) } return false } diff --git a/Server/src/main/content/global/skill/magic/SpellUtils.kt b/Server/src/main/content/global/skill/magic/SpellUtils.kt index ce84d606f..2f44a37e0 100644 --- a/Server/src/main/content/global/skill/magic/SpellUtils.kt +++ b/Server/src/main/content/global/skill/magic/SpellUtils.kt @@ -21,7 +21,45 @@ object SpellUtils { return false } - // Snowscape modifications: check the runeStachel container for the base runes if the player is carrying one + // Snowscape modifications: replaced entire "hasrune" function to only check the inventory once per rune, so the rune satchel has less overhead. + fun hasRune(p:Player,rune:Item):Boolean{ + if(usingStaff(p,rune.id)) return true + val removeItems = p.getAttribute("spell:runes",ArrayList()) + + val baseAmt = kotlin.math.max(p.inventory.getAmount(rune.id),(if (inEquipmentOrInventory(p, 10882)) p.runeSatchel.getAmount(rune.id) else 0)) + + if(baseAmt >= 0){ + removeItems.add(Item(rune.getId(),kotlin.math.min(baseAmt,rune.getAmount()))) + p.setAttribute("spell:runes",removeItems) + } + + var amtRemaining = rune.amount - baseAmt + val possibleComboRunes = CombinationRune.eligibleFor(Runes.forId(rune.id)) + for (r in possibleComboRunes) { + // Check if this combination rune was already added for a different element + for (alreadyListed in removeItems){ + if (alreadyListed.getId() == r.id){ + amtRemaining -= alreadyListed.getAmount() + } + } + + val amt = kotlin.math.max(p.inventory.getAmount(r.id),(if (inEquipmentOrInventory(p, 10882)) p.runeSatchel.getAmount(r.id) else 0)) + if (amt > 0 && amtRemaining > 0) { + + if (amtRemaining <= amt) { + removeItems.add(Item(r.id,amtRemaining)) + amtRemaining = 0 + break + } + removeItems.add(Item(r.id,amt)) + amtRemaining -= amt + } + } + p.setAttribute("spell:runes",removeItems) + return amtRemaining <= 0 + } + +/* Snowscape: Original function left here for easier merging of updates. fun hasRune(p:Player,rune:Item):Boolean{ val removeItems = p.getAttribute("spell:runes",ArrayList()) if(usingStaff(p,rune.id)) return true @@ -83,7 +121,7 @@ object SpellUtils { } return true } - +*/ fun attackableNPC(npc: NPC): Boolean{ return npc.definition.hasAction("attack") } diff --git a/Server/src/main/core/game/node/entity/combat/spell/MagicSpell.java b/Server/src/main/core/game/node/entity/combat/spell/MagicSpell.java index 250e9489d..aee3cbf05 100644 --- a/Server/src/main/core/game/node/entity/combat/spell/MagicSpell.java +++ b/Server/src/main/core/game/node/entity/combat/spell/MagicSpell.java @@ -278,6 +278,51 @@ public abstract class MagicSpell implements Plugin { * @param message the message. * @return {@code True} if so. */ + // Snowscape modifications: replaced entire "hasrune" function to only check the inventory once per rune, so the rune satchel has less overhead. + public boolean hasRune(Player p, Item item, List toRemove, boolean message) { + if (!usingStaff(p, item.getId())) { + boolean hasBaseRune = p.getInventory().contains(item.getId(),item.getAmount()) || (inEquipmentOrInventory(p, 10882,1) && p.runeSatchel.contains(item.getId(),item.getAmount())); + if(!hasBaseRune){ + int baseAmt = Math.max(p.getInventory().getAmount(item.getId()),((inEquipmentOrInventory(p, 10882,1)) ? p.runeSatchel.getAmount(item.getId()) : 0)); + if(baseAmt > 0){ + toRemove.add(new Item(item.getId(),Math.min(baseAmt,item.getAmount()))); + } + int amtRemaining = item.getAmount() - baseAmt; + List possibleComboRunes = CombinationRune.eligibleFor(Runes.forId(item.getId())); + for(CombinationRune r : possibleComboRunes){ + // Check if this combination rune was already added for a different element + for(Item alreadyListed : toRemove){ + if (alreadyListed.getId() == r.id){ + amtRemaining -= alreadyListed.getAmount(); + } + } + + int amt = Math.max(p.getInventory().getAmount(r.id),((inEquipmentOrInventory(p, 10882,1)) ? p.runeSatchel.getAmount(r.id) : 0)); + if(amt > 0 && amtRemaining > 0){ + + if(amtRemaining < amt){ + toRemove.add(new Item(r.id,amtRemaining)); + amtRemaining = 0; + continue; + } + amtRemaining -= amt; + toRemove.add(new Item(r.id,amt)); + } + } + if(amtRemaining <= 0){ + return true; + } else { + p.getPacketDispatch().sendMessage("You don't have enough " + item.getName() + "s to cast this spell."); + return false; + } + } + toRemove.add(item); + return true; + } + return true; + } + +/* Snowscape: Original function left here for easier merging of updates. public boolean hasRune(Player p, Item item, List toRemove, boolean message) { if (!usingStaff(p, item.getId())) { // Snowscape modification: check the rune satchel for the base runes if the player is carrying one @@ -313,6 +358,7 @@ public abstract class MagicSpell implements Plugin { } return true; } +*/ /** * Adds the experience for casting this spell. 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 436e83475..883a188a4 100644 --- a/Server/src/main/core/game/node/entity/player/Player.java +++ b/Server/src/main/core/game/node/entity/player/Player.java @@ -318,7 +318,7 @@ public class Player extends Entity { public final Container redSatchel = new Container(30, ContainerType.ALWAYS_STACK); public final Container blackSatchel = new Container(30, ContainerType.ALWAYS_STACK); public final Container goldSatchel = new Container(30, ContainerType.ALWAYS_STACK); - public final Container runeSatchel = new Container(30, ContainerType.ALWAYS_STACK); + public final Container runeSatchel = new Container(6, ContainerType.ALWAYS_STACK); // The summoning pouch storage public final Container summoningPouches = new Container(30); // The costume room bank