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.
This commit is contained in:
randy 2025-08-14 16:47:56 -06:00
parent cecdb97b19
commit 2ad90e9ed8
5 changed files with 89 additions and 10 deletions

View file

@ -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",

View file

@ -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
}

View file

@ -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<Item>())
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<Item>())
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")
}

View file

@ -278,6 +278,51 @@ public abstract class MagicSpell implements Plugin<SpellType> {
* @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<Item> 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<CombinationRune> 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<Item> 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<SpellType> {
}
return true;
}
*/
/**
* Adds the experience for casting this spell.

View file

@ -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