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.Sounds
import content.data.Quests
import core.game.event.SpellbookChangeEvent
import core.game.node.entity.player.link.SpellBookManager
class MagicAltarListener : InteractionListener {
override fun defineListeners() {
@ -46,15 +48,25 @@ class MagicAltarListener : InteractionListener {
player.skills.decrementPrayerPoints(player.skills.prayerPoints)
}
if (SpellBook.forInterface(player.spellBookManager.spellBook) == if (altar.id == ANCIENT_ALTAR) SpellBook.ANCIENT else SpellBook.LUNAR) {
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.update(player)
} else {
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.update(player)
}
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!")
player.spellBookManager.setSpellBook(SpellBook.MODERN)
player.spellBookManager.update(player)
} 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!")
player.spellBookManager.setSpellBook(if (altar.id == ANCIENT_ALTAR) SpellBook.ANCIENT else SpellBook.LUNAR)
player.spellBookManager.update(player)
}
}
companion object {

View file

@ -2,9 +2,12 @@ package content.global.skill.magic;
import core.game.component.Component;
import core.game.dialogue.DialoguePlugin;
import core.game.event.SpellbookChangeEvent;
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.plugin.Initializable;
/**
* Handles the SpellbookSwapDialogue dialogue.
@ -73,6 +76,11 @@ public class SpellbookSwapDialogue extends DialoguePlugin {
break;
}
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.getInterfaceManager().openTab(new Component(book.getInterfaceId()));
end();

View file

@ -24,12 +24,17 @@ import core.game.system.config.NPCConfigParser
import core.game.system.task.Pulse
import core.game.system.timer.impl.PoisonImmunity
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.RegionManager
import core.game.world.repository.Repository
import core.game.world.update.flag.context.Animation
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
class LunarListeners : SpellListener("lunar"), Commands {
@ -280,9 +285,14 @@ class LunarListeners : SpellListener("lunar"), Commands {
*/
// Level 96
/**
* Spellbook Swap
*/
onCast(Lunar.SPELLBOOK_SWAP, NONE) { player, _ ->
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
@ -785,9 +795,15 @@ class LunarListeners : SpellListener("lunar"), Commands {
*/
// Level 96
/**
* Spellbook Swap
*/
private fun spellbookSwap(player : Player) {
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
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 org.rs09.consts.Items
import content.data.Quests
import core.game.event.SpellbookChangeEvent
enum class SkillcapePerks(val attribute: String, val effect: ((Player) -> Unit)? = null) {
BAREFISTED_SMITHING("cape_perks:barefisted-smithing"),
@ -201,19 +202,21 @@ enum class SkillcapePerks(val attribute: String, val effect: ((Player) -> Unit)?
}
end()
if(spellbook != null){
if (spellbook == SpellBookManager.SpellBook.ANCIENT) {
if (!hasRequirement(player, Quests.DESERT_TREASURE))
return true
}
else if (spellbook == SpellBookManager.SpellBook.LUNAR) {
if (!hasRequirement(player, Quests.LUNAR_DIPLOMACY))
return true
}
player.spellBookManager.setSpellBook(spellbook)
player.interfaceManager.openTab(Component(spellbook.interfaceId))
player.incrementAttribute("/save:cape_perks:librarian-magus-charges",-1)
}
if (spellbook != null) {
if (spellbook == SpellBookManager.SpellBook.ANCIENT) {
if (!hasRequirement(player, Quests.DESERT_TREASURE)) 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.interfaceManager.openTab(Component(spellbook.interfaceId))
player.incrementAttribute("/save:cape_perks:librarian-magus-charges", -1)
}
return true
}

View file

@ -23,6 +23,7 @@ object Event {
@JvmStatic val AttributeSet = AttributeSetEvent::class.java
@JvmStatic val AttributeRemoved = AttributeRemoveEvent::class.java
@JvmStatic val SpellCast = SpellCastEvent::class.java
@JvmStatic val SpellbookChange = SpellbookChangeEvent::class.java
@JvmStatic val ItemAlchemized = ItemAlchemizationEvent::class.java
@JvmStatic val ItemEquipped = ItemEquipEvent::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.npc.NPC
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.prayer.PrayerType
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 AttributeRemoveEvent(val entity: Entity, val attribute: String) : 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 ItemEquipEvent(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;
}
/**
* 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.
* @author 'Vexia
@ -134,5 +144,4 @@ public final class SpellBookManager {
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)
}
}