Fixed bugs relating to player location and random events

Improved handling of random events when the location of the abducted player is missing from save file
Added per-tick auditing of data relating to player location
This commit is contained in:
Player Name 2024-10-12 04:21:49 +00:00 committed by Ryan
parent 393752d77b
commit 32cd17bfa2
10 changed files with 63 additions and 32 deletions

View file

@ -79,7 +79,7 @@ class DrillDemonListeners : InteractionListener, MapArea {
} }
override fun getRestrictions(): Array<ZoneRestriction> { override fun getRestrictions(): Array<ZoneRestriction> {
return arrayOf(ZoneRestriction.RANDOM_EVENTS, ZoneRestriction.CANNON, ZoneRestriction.FOLLOWERS) return arrayOf(ZoneRestriction.RANDOM_EVENTS, ZoneRestriction.CANNON, ZoneRestriction.FOLLOWERS, ZoneRestriction.OFF_MAP)
} }
override fun areaEnter(entity: Entity) { override fun areaEnter(entity: Entity) {
@ -90,4 +90,4 @@ class DrillDemonListeners : InteractionListener, MapArea {
setComponentVisibility(entity.asPlayer(), 746, 12, true) setComponentVisibility(entity.asPlayer(), 746, 12, true)
} }
} }
} }

View file

@ -1,5 +1,6 @@
package content.global.ame.events.drilldemon package content.global.ame.events.drilldemon
import core.ServerConstants
import core.api.* import core.api.*
import core.game.interaction.QueueStrength import core.game.interaction.QueueStrength
import core.game.node.entity.player.Player import core.game.node.entity.player.Player
@ -67,7 +68,8 @@ object DrillDemonUtils {
fun cleanup(player: Player) { fun cleanup(player: Player) {
player.locks.unlockTeleport() player.locks.unlockTeleport()
unlock(player) unlock(player)
teleport(player, getAttribute(player, DD_KEY_RETURN_LOC, Location.create(3222, 3218, 0))) val destination = getAttribute(player, DD_KEY_RETURN_LOC, ServerConstants.HOME_LOCATION ?: Location.create(3222, 3218, 0))
teleport(player, destination)
removeAttribute(player, DD_KEY_RETURN_LOC) removeAttribute(player, DD_KEY_RETURN_LOC)
removeAttribute(player, DD_KEY_TASK) removeAttribute(player, DD_KEY_TASK)
removeAttribute(player, DD_CORRECT_OFFSET) removeAttribute(player, DD_CORRECT_OFFSET)

View file

@ -121,7 +121,8 @@ class EvilBobListeners : InteractionListener, MapArea {
} }
3 -> { 3 -> {
sendMessage(player, "Welcome back to ${ServerConstants.SERVER_NAME}.") sendMessage(player, "Welcome back to ${ServerConstants.SERVER_NAME}.")
teleport(player, getAttribute(player, EvilBobUtils.prevLocation, Location.create(3222, 3219, 0))) val destination = getAttribute(player, EvilBobUtils.prevLocation, ServerConstants.HOME_LOCATION ?: Location.create(3222, 3218, 0))
teleport(player, destination)
EvilBobUtils.reward(player) EvilBobUtils.reward(player)
EvilBobUtils.cleanup(player) EvilBobUtils.cleanup(player)
resetAnimator(player) resetAnimator(player)
@ -139,7 +140,7 @@ class EvilBobListeners : InteractionListener, MapArea {
} }
override fun getRestrictions(): Array<ZoneRestriction> { override fun getRestrictions(): Array<ZoneRestriction> {
return arrayOf(ZoneRestriction.RANDOM_EVENTS, ZoneRestriction.CANNON, ZoneRestriction.FOLLOWERS) return arrayOf(ZoneRestriction.RANDOM_EVENTS, ZoneRestriction.CANNON, ZoneRestriction.FOLLOWERS, ZoneRestriction.OFF_MAP)
} }
override fun areaEnter(entity: Entity) { override fun areaEnter(entity: Entity) {

View file

@ -1,5 +1,6 @@
package content.global.ame.events.evilbob package content.global.ame.events.evilbob
import core.ServerConstants
import core.api.* import core.api.*
import core.game.node.entity.player.Player import core.game.node.entity.player.Player
import core.game.node.entity.skill.Skills import core.game.node.entity.skill.Skills
@ -60,7 +61,7 @@ object EvilBobUtils {
fun cleanup(player: Player) { fun cleanup(player: Player) {
player.locks.unlockTeleport() player.locks.unlockTeleport()
player.properties.teleportLocation = getAttribute(player, prevLocation, null) player.properties.teleportLocation = getAttribute(player, prevLocation, ServerConstants.HOME_LOCATION)
removeAttributes(player, assignedFishingZone, eventComplete, prevLocation, attentive, servantHelpDialogueSeen, attentiveNewSpot, startingDialogueSeen) removeAttributes(player, assignedFishingZone, eventComplete, prevLocation, attentive, servantHelpDialogueSeen, attentiveNewSpot, startingDialogueSeen)
removeAll(player, Items.FISHLIKE_THING_6202) removeAll(player, Items.FISHLIKE_THING_6202)
removeAll(player, Items.FISHLIKE_THING_6202, Container.BANK) removeAll(player, Items.FISHLIKE_THING_6202, Container.BANK)

View file

@ -57,10 +57,10 @@ class FreakListeners : InteractionListener, MapArea {
} }
override fun getRestrictions(): Array<ZoneRestriction> { override fun getRestrictions(): Array<ZoneRestriction> {
return arrayOf(ZoneRestriction.RANDOM_EVENTS, ZoneRestriction.CANNON, ZoneRestriction.FOLLOWERS) return arrayOf(ZoneRestriction.RANDOM_EVENTS, ZoneRestriction.CANNON, ZoneRestriction.FOLLOWERS, ZoneRestriction.OFF_MAP)
} }
override fun areaEnter(entity: Entity) { override fun areaEnter(entity: Entity) {
entity.locks.lockTeleport(1000000) entity.locks.lockTeleport(1000000)
} }
} }

View file

@ -1,5 +1,6 @@
package content.global.ame.events.freakyforester package content.global.ame.events.freakyforester
import core.ServerConstants
import core.api.* import core.api.*
import org.rs09.consts.Items import org.rs09.consts.Items
import org.rs09.consts.NPCs import org.rs09.consts.NPCs
@ -35,7 +36,7 @@ object FreakUtils{
fun cleanup(player: Player) { fun cleanup(player: Player) {
player.locks.unlockTeleport() player.locks.unlockTeleport()
player.properties.teleportLocation = getAttribute(player,freakPreviousLoc,null) player.properties.teleportLocation = getAttribute(player,freakPreviousLoc, ServerConstants.HOME_LOCATION)
removeAttributes(player, freakPreviousLoc, freakTask, freakComplete, pheasantKilled) removeAttributes(player, freakPreviousLoc, freakTask, freakComplete, pheasantKilled)
removeAll(player, Items.RAW_PHEASANT_6178) removeAll(player, Items.RAW_PHEASANT_6178)
removeAll(player, Items.RAW_PHEASANT_6178, Container.BANK) removeAll(player, Items.RAW_PHEASANT_6178, Container.BANK)

View file

@ -9,16 +9,17 @@ import org.rs09.consts.NPCs
import core.game.interaction.InteractionListener import core.game.interaction.InteractionListener
import core.game.interaction.IntType import core.game.interaction.IntType
import content.global.handlers.iface.ExperienceInterface import content.global.handlers.iface.ExperienceInterface
import core.api.MapArea
import core.game.world.map.zone.ZoneBorders
import core.game.world.map.zone.ZoneRestriction
class SupriseExamListeners : InteractionListener { class SupriseExamListeners : InteractionListener, MapArea {
val MORDAUT = NPCs.MR_MORDAUT_6117
val BOOK_OF_KNOWLEDGE = Items.BOOK_OF_KNOWLEDGE_11640
override fun defineListeners() { override fun defineListeners() {
on(MORDAUT, IntType.NPC, "talk-to"){ player, node -> on(NPCs.MR_MORDAUT_6117, IntType.NPC, "talk-to") { player, node ->
player.faceLocation(Location.create(1886, 5024, 0)) player.faceLocation(Location.create(1886, 5024, 0))
val examComplete = player.getAttribute(SurpriseExamUtils.SE_KEY_CORRECT,0) == 3 val examComplete = player.getAttribute(SurpriseExamUtils.SE_KEY_CORRECT, 0) == 3
player.dialogueInterpreter.open(MordautDialogue(examComplete),node.asNpc()) player.dialogueInterpreter.open(MordautDialogue(examComplete), node.asNpc())
return@on true return@on true
} }
@ -39,9 +40,9 @@ class SupriseExamListeners : InteractionListener {
return@on true return@on true
} }
on(BOOK_OF_KNOWLEDGE, IntType.ITEM, "read"){ player, _ -> on(Items.BOOK_OF_KNOWLEDGE_11640, IntType.ITEM, "read") { player, _ ->
player.setAttribute("caller"){skill: Int,p: Player -> player.setAttribute("caller") { skill: Int, p: Player ->
if(p.inventory.remove(Item(BOOK_OF_KNOWLEDGE))) { if (p.inventory.remove(Item(Items.BOOK_OF_KNOWLEDGE_11640))) {
val level = p.skills.getStaticLevel(skill) val level = p.skills.getStaticLevel(skill)
val experience = level * 15.0 val experience = level * 15.0
p.skills.addExperience(skill, experience) p.skills.addExperience(skill, experience)
@ -54,8 +55,16 @@ class SupriseExamListeners : InteractionListener {
} }
override fun defineDestinationOverrides() { override fun defineDestinationOverrides() {
setDest(IntType.NPC,MORDAUT){ _, _ -> setDest(IntType.NPC, NPCs.MR_MORDAUT_6117) { _, _ ->
return@setDest Location.create(1886, 5025, 0) return@setDest Location.create(1886, 5025, 0)
} }
} }
}
override fun defineAreaBorders(): Array<ZoneBorders> {
return arrayOf(ZoneBorders.forRegion(7502))
}
override fun getRestrictions(): Array<ZoneRestriction> {
return arrayOf(ZoneRestriction.RANDOM_EVENTS, ZoneRestriction.CANNON, ZoneRestriction.FOLLOWERS, ZoneRestriction.OFF_MAP)
}
}

View file

@ -1,5 +1,6 @@
package content.global.ame.events.supriseexam package content.global.ame.events.supriseexam
import core.Server
import core.api.* import core.api.*
import core.game.node.entity.impl.PulseType import core.game.node.entity.impl.PulseType
import core.game.node.entity.player.Player import core.game.node.entity.player.Player
@ -40,17 +41,12 @@ object SurpriseExamUtils {
} }
fun cleanup(player: Player){ fun cleanup(player: Player){
player.properties.teleportLocation = player.getAttribute(SE_KEY_LOC,null) player.properties.teleportLocation = player.getAttribute(SE_KEY_LOC, ServerConstants.HOME_LOCATION)
clearLogoutListener(player, SE_LOGOUT_KEY) clearLogoutListener(player, SE_LOGOUT_KEY)
player.removeAttribute(SE_KEY_LOC) removeAttributes(player, SE_KEY_LOC, SE_KEY_INDEX, SE_KEY_CORRECT)
player.removeAttribute(SE_KEY_INDEX)
player.removeAttribute(SE_KEY_CORRECT)
player.pulseManager.run(object : Pulse(2){ player.pulseManager.run(object : Pulse(2){
override fun pulse(): Boolean { override fun pulse(): Boolean {
val reward = Item(Items.BOOK_OF_KNOWLEDGE_11640) addItemOrDrop(player, Items.BOOK_OF_KNOWLEDGE_11640)
if(!player.inventory.add(reward)){
GroundItemManager.create(reward,player)
}
return true return true
} }
}, PulseType.CUSTOM_1) }, PulseType.CUSTOM_1)

View file

@ -2,6 +2,7 @@ package core.game.node.entity.player;
import content.global.handlers.item.equipment.special.SalamanderSwingHandler; import content.global.handlers.item.equipment.special.SalamanderSwingHandler;
import content.global.skill.runecrafting.PouchManager; import content.global.skill.runecrafting.PouchManager;
import core.api.ContentAPIKt;
import core.api.EquipmentSlot; import core.api.EquipmentSlot;
import core.game.component.Component; import core.game.component.Component;
import core.game.container.Container; import core.game.container.Container;
@ -44,6 +45,7 @@ import core.game.system.task.Pulse;
import core.game.world.map.*; import core.game.world.map.*;
import core.game.world.map.build.DynamicRegion; import core.game.world.map.build.DynamicRegion;
import core.game.world.map.path.Pathfinder; import core.game.world.map.path.Pathfinder;
import core.game.world.map.zone.ZoneRestriction;
import core.game.world.map.zone.ZoneType; import core.game.world.map.zone.ZoneType;
import core.game.world.update.flag.PlayerFlags; import core.game.world.update.flag.PlayerFlags;
import core.game.world.update.flag.*; import core.game.world.update.flag.*;
@ -475,11 +477,22 @@ public class Player extends Entity {
settings.setSpecialEnergy(100); settings.setSpecialEnergy(100);
} }
//Decrements prayer points // Decrement prayer points
getPrayer().tick(); getPrayer().tick();
//update wealth tracking // Update wealth tracking
checkForWealthUpdate(false); checkForWealthUpdate(false);
// Check if the player is on the map
// This is only a sanity check to detect improper usage of the 'original-loc' attribute, hence only do this work if the attribute is set
if (ContentAPIKt.getAttribute(this, "/save:original-loc", null) != null) {
int rid = location.getRegionId();
Region r = RegionManager.forId(rid);
if (!(r instanceof DynamicRegion) && !getZoneMonitor().isRestricted(ZoneRestriction.OFF_MAP)) {
log(this.getClass(), Log.ERR, "Player " + getUsername() + " has the original-loc attribute set but isn't actually off-map! This indicates a bug in the code that set that attribute. The original-loc is: " + getAttribute("/save:original-loc") + ", good luck debugging!");
ContentAPIKt.removeAttribute(this, "original-loc");
}
}
} }
private void checkForWealthUpdate(boolean force) { private void checkForWealthUpdate(boolean force) {

View file

@ -31,7 +31,7 @@ public enum ZoneRestriction {
*/ */
CANNON, CANNON,
/** /**
* Do not spawn a grave if a player dies here * Do not spawn a grave if a player dies here.
*/ */
GRAVES, GRAVES,
@ -39,6 +39,14 @@ public enum ZoneRestriction {
* No teleporting allowed. * No teleporting allowed.
*/ */
TELEPORT, TELEPORT,
/**
* This region is not a part of the normal overworld or cave system.
* Used for temporary areas that use the 'original-loc' attribute to teleport the player back when they are done in the area.
* Example: non-dynamic/non-instanced random-event areas (e.g. Damien's bootcamp)
* Dynamic regions are implicitly off-map and do not require this attribute.
*/
OFF_MAP,
; ;
/** /**
@ -48,4 +56,4 @@ public enum ZoneRestriction {
public int getFlag() { public int getFlag() {
return 1 << ordinal(); return 1 << ordinal();
} }
} }