Converted SpellBookSwapSpell.java to a listener, added SpellbookSwap.kt timer, added SpellbookChangeEvent

This commit is contained in:
Damighty 2025-11-27 22:37:18 +02:00
parent 3a64435691
commit c8aab64673
No known key found for this signature in database
GPG key ID: 7964BED6F70C87F0
9 changed files with 153 additions and 117 deletions

View file

@ -10,6 +10,8 @@ import core.game.node.entity.skill.Skills
import org.rs09.consts.Scenery import org.rs09.consts.Scenery
import org.rs09.consts.Sounds import org.rs09.consts.Sounds
import content.data.Quests import content.data.Quests
import core.game.event.SpellbookChangeEvent
import core.game.node.entity.player.link.SpellBookManager
class MagicAltarListener : InteractionListener { class MagicAltarListener : InteractionListener {
override fun defineListeners() { override fun defineListeners() {
@ -47,10 +49,20 @@ class MagicAltarListener : InteractionListener {
} }
if (SpellBook.forInterface(player.spellBookManager.spellBook) == if (altar.id == ANCIENT_ALTAR) SpellBook.ANCIENT else SpellBook.LUNAR) { if (SpellBook.forInterface(player.spellBookManager.spellBook) == if (altar.id == ANCIENT_ALTAR) SpellBook.ANCIENT else SpellBook.LUNAR) {
player.dispatch(SpellbookChangeEvent(
SpellBook.forInterface(player.spellBookManager.spellBook),
SpellBook.MODERN,
SpellBookManager.SpellbookChangeSource.ALTAR)
)
sendMessage(player, if (altar.id == ANCIENT_ALTAR) "You feel a strange drain upon your memory..." else "Modern spells activated!") sendMessage(player, if (altar.id == ANCIENT_ALTAR) "You feel a strange drain upon your memory..." else "Modern spells activated!")
player.spellBookManager.setSpellBook(SpellBook.MODERN) player.spellBookManager.setSpellBook(SpellBook.MODERN)
player.spellBookManager.update(player) player.spellBookManager.update(player)
} else { } else {
player.dispatch(SpellbookChangeEvent(
SpellBook.forInterface(player.spellBookManager.spellBook),
if (altar.id == ANCIENT_ALTAR) SpellBook.ANCIENT else SpellBook.LUNAR,
SpellBookManager.SpellbookChangeSource.ALTAR)
)
sendMessage(player, if (altar.id == ANCIENT_ALTAR) "You feel a strange wisdom fill your mind..." else "Lunar spells activated!") sendMessage(player, if (altar.id == ANCIENT_ALTAR) "You feel a strange wisdom fill your mind..." else "Lunar spells activated!")
player.spellBookManager.setSpellBook(if (altar.id == ANCIENT_ALTAR) SpellBook.ANCIENT else SpellBook.LUNAR) player.spellBookManager.setSpellBook(if (altar.id == ANCIENT_ALTAR) SpellBook.ANCIENT else SpellBook.LUNAR)
player.spellBookManager.update(player) player.spellBookManager.update(player)

View file

@ -2,9 +2,12 @@ package content.global.skill.magic;
import core.game.component.Component; import core.game.component.Component;
import core.game.dialogue.DialoguePlugin; import core.game.dialogue.DialoguePlugin;
import core.game.event.SpellbookChangeEvent;
import core.game.node.entity.player.Player; import core.game.node.entity.player.Player;
import core.plugin.Initializable; import core.game.node.entity.player.link.SpellBookManager.SpellbookChangeSource;
import core.game.node.entity.player.link.SpellBookManager.SpellBook; import core.game.node.entity.player.link.SpellBookManager.SpellBook;
import core.plugin.Initializable;
/** /**
* Handles the SpellbookSwapDialogue dialogue. * Handles the SpellbookSwapDialogue dialogue.
@ -73,6 +76,11 @@ public class SpellbookSwapDialogue extends DialoguePlugin {
break; break;
} }
final SpellBook book = type == 1 ? SpellBook.ANCIENT : SpellBook.MODERN; final SpellBook book = type == 1 ? SpellBook.ANCIENT : SpellBook.MODERN;
player.dispatch(new SpellbookChangeEvent(
SpellBook.LUNAR,
book,
SpellbookChangeSource.SPELLBOOK_SWAP_CAST)
);
player.getSpellBookManager().setSpellBook(book); player.getSpellBookManager().setSpellBook(book);
player.getInterfaceManager().openTab(new Component(book.getInterfaceId())); player.getInterfaceManager().openTab(new Component(book.getInterfaceId()));
end(); end();

View file

@ -24,12 +24,17 @@ import core.game.system.config.NPCConfigParser
import core.game.system.task.Pulse import core.game.system.task.Pulse
import core.game.system.timer.impl.PoisonImmunity import core.game.system.timer.impl.PoisonImmunity
import core.game.system.timer.impl.SkillRestore import core.game.system.timer.impl.SkillRestore
import core.game.system.timer.impl.SpellbookSwap
import core.game.world.map.Location import core.game.world.map.Location
import core.game.world.map.RegionManager import core.game.world.map.RegionManager
import core.game.world.repository.Repository import core.game.world.repository.Repository
import core.game.world.update.flag.context.Animation import core.game.world.update.flag.context.Animation
import core.tools.RandomFunction import core.tools.RandomFunction
import org.rs09.consts.* import org.rs09.consts.Animations
import org.rs09.consts.Components
import org.rs09.consts.Graphics
import org.rs09.consts.Items
import org.rs09.consts.Sounds
import kotlin.math.floor import kotlin.math.floor
class LunarListeners : SpellListener("lunar"), Commands { class LunarListeners : SpellListener("lunar"), Commands {
@ -280,9 +285,14 @@ class LunarListeners : SpellListener("lunar"), Commands {
*/ */
// Level 96 // Level 96
/** onCast(Lunar.SPELLBOOK_SWAP, NONE) { player, _ ->
* Spellbook Swap requires(player, 96, arrayOf(
*/ Item(Items.LAW_RUNE_563, 1),
Item(Items.COSMIC_RUNE_564, 2),
Item(Items.ASTRAL_RUNE_9075, 3)
))
spellbookSwap(player)
}
} }
// Spell handlers // Spell handlers
@ -785,9 +795,15 @@ class LunarListeners : SpellListener("lunar"), Commands {
*/ */
// Level 96 // Level 96
/** private fun spellbookSwap(player : Player) {
* Spellbook Swap removeRunes(player, true)
*/ lock(player, 9)
visualizeSpell(player, 6299, 1062)
player.dialogueInterpreter.open(3264731)
registerTimer(player, SpellbookSwap())
addXP(player, 130.0)
setDelay(player, false)
}
// Other/Multi spell use-case // Other/Multi spell use-case
private fun sendTeleport(player: Player, xp: Double, loc: Location){ private fun sendTeleport(player: Player, xp: Double, loc: Location){

View file

@ -1,86 +0,0 @@
package content.global.skill.magic.lunar;
import core.game.component.Component;
import core.game.node.entity.combat.spell.MagicSpell;
import core.game.node.entity.combat.spell.Runes;
import core.game.node.Node;
import core.game.node.entity.Entity;
import core.game.node.entity.combat.spell.SpellType;
import core.game.node.entity.player.Player;
import core.game.node.entity.player.link.SpellBookManager.SpellBook;
import core.game.node.item.Item;
import core.game.system.task.Pulse;
import core.game.world.GameWorld;
import core.game.world.update.flag.context.Animation;
import core.game.world.update.flag.context.Graphics;
import core.plugin.Initializable;
import core.plugin.Plugin;
import core.tools.RandomFunction;
import static core.tools.TickUtilsKt.minutesToTicks;
/**
* The spellbook swap spell.
* @author 'Vexia
*/
@Initializable
public class SpellbookSwapSpell extends MagicSpell {
/**
* Represents the animation of this spell.
*/
private final Animation ANIMATION = new Animation(6299);
/**
* Represents the graphics of this spell.
*/
private final Graphics GRAPHIC = new Graphics(1062);
/**
* Constructs a new {@code SpellbookSwapSpell} {@code Object}.
*/
public SpellbookSwapSpell() {
super(SpellBook.LUNAR, 96, 130, null, null, null, new Item[] { new Item(Runes.LAW_RUNE.getId(), 1), new Item(Runes.COSMIC_RUNE.getId(), 2), new Item(Runes.ASTRAL_RUNE.getId(), 3) });
}
@Override
public Plugin<SpellType> newInstance(SpellType arg) throws Throwable {
SpellBook.LUNAR.register(12, this);
return this;
}
@Override
public boolean cast(Entity entity, Node target) {
final Player player = (Player) entity;
if (!super.meetsRequirements(player, true, true)) {
return false;
}
player.lock(9);
player.animate(ANIMATION);
player.graphics(GRAPHIC);
player.getDialogueInterpreter().open(3264731);
final int id = RandomFunction.random(1, 500000);
player.setAttribute("spell:swap", id);
GameWorld.getPulser().submit(new Pulse(minutesToTicks(2), player) {
@Override
public boolean pulse() {
if (player.getAttribute("spell:swap", 0) == id) {
removeTemporarySpell(player);
}
return true;
}
});
return true;
}
/**
* Method used to remove the temp spell swap.
* @param player the player.
*/
public static void removeTemporarySpell(final Player player) {
player.removeAttribute("spell:swap");
player.getSpellBookManager().setSpellBook(SpellBook.LUNAR);
player.getInterfaceManager().openTab(new Component(SpellBook.LUNAR.getInterfaceId()));
}
}

View file

@ -18,6 +18,7 @@ import core.cache.def.impl.ItemDefinition
import core.tools.END_DIALOGUE import core.tools.END_DIALOGUE
import org.rs09.consts.Items import org.rs09.consts.Items
import content.data.Quests import content.data.Quests
import core.game.event.SpellbookChangeEvent
enum class SkillcapePerks(val attribute: String, val effect: ((Player) -> Unit)? = null) { enum class SkillcapePerks(val attribute: String, val effect: ((Player) -> Unit)? = null) {
BAREFISTED_SMITHING("cape_perks:barefisted-smithing"), BAREFISTED_SMITHING("cape_perks:barefisted-smithing"),
@ -203,13 +204,15 @@ enum class SkillcapePerks(val attribute: String, val effect: ((Player) -> Unit)?
end() end()
if (spellbook != null) { if (spellbook != null) {
if (spellbook == SpellBookManager.SpellBook.ANCIENT) { if (spellbook == SpellBookManager.SpellBook.ANCIENT) {
if (!hasRequirement(player, Quests.DESERT_TREASURE)) if (!hasRequirement(player, Quests.DESERT_TREASURE)) return true
return true } else if (spellbook == SpellBookManager.SpellBook.LUNAR) {
} if (!hasRequirement(player, Quests.LUNAR_DIPLOMACY)) return true
else if (spellbook == SpellBookManager.SpellBook.LUNAR) {
if (!hasRequirement(player, Quests.LUNAR_DIPLOMACY))
return true
} }
player.dispatch(SpellbookChangeEvent(
SpellBookManager.SpellBook.forInterface(player.spellBookManager.spellBook),
spellbook,
SpellBookManager.SpellbookChangeSource.MAGIC_CAPE_PERK)
)
player.spellBookManager.setSpellBook(spellbook) player.spellBookManager.setSpellBook(spellbook)
player.interfaceManager.openTab(Component(spellbook.interfaceId)) player.interfaceManager.openTab(Component(spellbook.interfaceId))
player.incrementAttribute("/save:cape_perks:librarian-magus-charges", -1) player.incrementAttribute("/save:cape_perks:librarian-magus-charges", -1)

View file

@ -23,6 +23,7 @@ object Event {
@JvmStatic val AttributeSet = AttributeSetEvent::class.java @JvmStatic val AttributeSet = AttributeSetEvent::class.java
@JvmStatic val AttributeRemoved = AttributeRemoveEvent::class.java @JvmStatic val AttributeRemoved = AttributeRemoveEvent::class.java
@JvmStatic val SpellCast = SpellCastEvent::class.java @JvmStatic val SpellCast = SpellCastEvent::class.java
@JvmStatic val SpellbookChange = SpellbookChangeEvent::class.java
@JvmStatic val ItemAlchemized = ItemAlchemizationEvent::class.java @JvmStatic val ItemAlchemized = ItemAlchemizationEvent::class.java
@JvmStatic val ItemEquipped = ItemEquipEvent::class.java @JvmStatic val ItemEquipped = ItemEquipEvent::class.java
@JvmStatic val ItemUnequipped = ItemUnequipEvent::class.java @JvmStatic val ItemUnequipped = ItemUnequipEvent::class.java

View file

@ -6,6 +6,7 @@ import core.game.node.Node
import core.game.node.entity.Entity import core.game.node.entity.Entity
import core.game.node.entity.npc.NPC import core.game.node.entity.npc.NPC
import core.game.node.entity.player.link.SpellBookManager.SpellBook import core.game.node.entity.player.link.SpellBookManager.SpellBook
import core.game.node.entity.player.link.SpellBookManager.SpellbookChangeSource
import core.game.node.entity.player.link.TeleportManager.TeleportType import core.game.node.entity.player.link.TeleportManager.TeleportType
import core.game.node.entity.player.link.prayer.PrayerType import core.game.node.entity.player.link.prayer.PrayerType
import core.game.node.item.Item import core.game.node.item.Item
@ -34,6 +35,7 @@ data class InterfaceCloseEvent(val component: Component) : Event
data class AttributeSetEvent(val entity: Entity, val attribute: String, val value: Any) : Event data class AttributeSetEvent(val entity: Entity, val attribute: String, val value: Any) : Event
data class AttributeRemoveEvent(val entity: Entity, val attribute: String) : Event data class AttributeRemoveEvent(val entity: Entity, val attribute: String) : Event
data class SpellCastEvent(val spellBook: SpellBook, val spellId: Int, val target: Node? = null) : Event data class SpellCastEvent(val spellBook: SpellBook, val spellId: Int, val target: Node? = null) : Event
data class SpellbookChangeEvent(val oldSpellBook: SpellBook, val newSpellBook: SpellBook, val source: SpellbookChangeSource) : Event
data class ItemAlchemizationEvent(val itemId: Int, val isHigh: Boolean) : Event data class ItemAlchemizationEvent(val itemId: Int, val isHigh: Boolean) : Event
data class ItemEquipEvent(val itemId: Int, val slotId: Int) : Event data class ItemEquipEvent(val itemId: Int, val slotId: Int) : Event
data class ItemUnequipEvent(val itemId: Int, val slotId: Int) : Event data class ItemUnequipEvent(val itemId: Int, val slotId: Int) : Event

View file

@ -55,6 +55,16 @@ public final class SpellBookManager {
return spellBook; return spellBook;
} }
/**
* All the possible ways a SpellBook can get changed.
*/
public enum SpellbookChangeSource {
ALTAR,
MAGIC_CAPE_PERK,
SPELLBOOK_SWAP_CAST,
SPELLBOOK_SWAP_RESTORE
}
/** /**
* Represents a characters spell book. * Represents a characters spell book.
* @author 'Vexia * @author 'Vexia
@ -134,5 +144,4 @@ public final class SpellBookManager {
return spells.get(buttonId); return spells.get(buttonId);
} }
} }
} }

View file

@ -0,0 +1,71 @@
package core.game.system.timer.impl
import core.api.Event.SpellCast
import core.api.Event.SpellbookChange
import core.api.removeTimer
import core.game.event.EventHook
import core.game.event.SpellCastEvent
import core.game.event.SpellbookChangeEvent
import core.game.node.entity.Entity
import core.game.node.entity.player.Player
import core.game.node.entity.player.link.SpellBookManager.*
import core.game.system.timer.PersistTimer
import core.tools.minutesToTicks
class SpellbookSwap : PersistTimer(runInterval = minutesToTicks(2), identifier = "spellbook:swap") {
private val spellCastHook = object : EventHook<SpellCastEvent> {
override fun process(entity : Entity, event : SpellCastEvent) {
if (event.spellBook == SpellBook.LUNAR && event.spellId == 12) return
revertSpellbook(entity)
removeTimer<SpellbookSwap>(entity)
}
}
private val spellBookChangeHook = object : EventHook<SpellbookChangeEvent> {
override fun process(entity : Entity, event : SpellbookChangeEvent) {
if (event.source != SpellbookChangeSource.SPELLBOOK_SWAP_CAST && event.source != SpellbookChangeSource.SPELLBOOK_SWAP_RESTORE) {
removeTimer<SpellbookSwap>(entity)
}
}
}
override fun run(entity : Entity) : Boolean {
revertSpellbook(entity)
return true
}
override fun onRegister(entity : Entity) {
entity.hook(SpellCast, spellCastHook)
entity.hook(SpellbookChange, spellBookChangeHook)
/*
if (entity is Player) {
registerLogoutListener(entity, "spellbook:swap") { player ->
revertSpellbook(player)
}
}
*/
}
override fun onRemoval(entity : Entity) {
entity.unhook(spellCastHook)
entity.unhook(spellBookChangeHook)
/*
if (entity is Player) {
clearLogoutListener(entity, "spellbook:swap")
}
*/
}
private fun revertSpellbook(entity : Entity) {
if (entity !is Player) return
if (SpellBook.forInterface(entity.spellBookManager.spellBook) == SpellBook.LUNAR) return
entity.dispatch(SpellbookChangeEvent(
SpellBook.forInterface(entity.spellBookManager.spellBook),
SpellBook.LUNAR,
SpellbookChangeSource.SPELLBOOK_SWAP_RESTORE)
)
entity.spellBookManager.setSpellBook(SpellBook.LUNAR)
entity.spellBookManager.update(entity)
}
}