Random Events should now spawn correctly

Fixed an issue that was causing tick event hooks to not fire
This commit is contained in:
Ceikry
2022-05-16 12:22:29 +00:00
committed by Ryan
parent 8835799230
commit 07065c7e79
8 changed files with 67 additions and 9 deletions
@@ -2,6 +2,7 @@ package core.game.node.entity;
import api.events.Event;
import api.events.EventHook;
import api.events.TickEvent;
import core.game.content.holiday.HolidayEvent;
import core.game.interaction.DestinationFlag;
import core.game.node.Node;
@@ -216,6 +217,7 @@ public abstract class Entity extends Node {
* This methods gets called before the {@link #update()} method.
*/
public void tick() {
dispatch(new TickEvent(GameWorld.getTicks()));
skills.pulse();
walkingQueue.update();
updateMasks.prepare(this);
@@ -70,6 +70,9 @@ public final class WalkingQueue {
boolean isPlayer = entity instanceof Player;
this.walkDir = -1;
this.runDir = -1;
if(entity.getLocation() == null) {
return;
}
if (updateTeleport()) {
return;
}
+1 -1
View File
@@ -13,4 +13,4 @@ data class InteractionEvent(val target: Node, val option: String) : Event
data class ButtonClickedEvent(val iface: Int, val buttonId: Int) : Event
data class UsedWithEvent(val used: Int, val with: Int) : Event
data class SelfDeath(val killer: Entity) : Event
data class TickEvent(val source: Entity) : Event
data class TickEvent(val worldTicks: Int) : Event
@@ -14,9 +14,6 @@ import rs09.game.system.SystemLogger
import rs09.game.world.GameWorld
import kotlin.random.Random
private const val AVG_DELAY_TICKS = 6000 // 60 minutes
private const val MIN_DELAY_TICKS = AVG_DELAY_TICKS / 2
private const val MAX_DELAY_TICKS = MIN_DELAY_TICKS + AVG_DELAY_TICKS // window of 60 min centered on 60 min (30 to 90 min)
class RandomEventManager(val player: Player? = null) : LoginListener, EventHook<TickEvent> {
var event: RandomEventNPC? = null
var enabled: Boolean = false
@@ -47,7 +44,7 @@ class RandomEventManager(val player: Player? = null) : LoginListener, EventHook<
return
}
if (getAttribute<RandomEventNPC?>(player, "re-npc", null) != null) return
val currentAction = player.pulseManager.current.toString()
val currentAction = player.pulseManager.current?.toString() ?: "None"
val ame: RandomEvents = if(currentAction.contains("WoodcuttingSkillPulse") && Random.nextBoolean()){
RandomEvents.TREE_SPIRIT
} else if(currentAction.contains("FishingPulse") && Random.nextBoolean()){
@@ -62,6 +59,7 @@ class RandomEventManager(val player: Player? = null) : LoginListener, EventHook<
event = ame.npc.create(player,ame.loot,ame.type)
if (event!!.spawnLocation == null) {
nextSpawn = GameWorld.ticks + 3000
SystemLogger.logWarn("Tried to spawn random event for ${player.username} but spawn location was null!")
return
}
event!!.init()
@@ -74,6 +72,10 @@ class RandomEventManager(val player: Player? = null) : LoginListener, EventHook<
}
companion object {
const val AVG_DELAY_TICKS = 6000 // 60 minutes
const val MIN_DELAY_TICKS = AVG_DELAY_TICKS / 2
const val MAX_DELAY_TICKS = MIN_DELAY_TICKS + AVG_DELAY_TICKS // window of 60 min centered on 60 min (30 to 90 min)
@JvmStatic fun getInstance(player: Player): RandomEventManager?
{
return getAttribute(player, "random-manager", null)
@@ -9,6 +9,7 @@ import core.tools.RandomFunction
import org.rs09.consts.Items
import rs09.game.content.ame.RandomEventNPC
import rs09.game.content.global.WeightBasedTable
import java.lang.Integer.max
val ids = 2463..2468
@@ -18,7 +19,7 @@ class EvilChickenNPC(override var loot: WeightBasedTable? = null) : RandomEventN
override fun init() {
super.init()
val index = (player.properties.combatLevel / 20) - 1
val index = max(0, (player.properties.combatLevel / 20) - 1)
val id = ids.toList()[index]
this.transform(id)
this.attack(player)
@@ -38,7 +38,7 @@ class UpdateSequence
playersList = renderablePlayers
npcList = Repository.renderableNpcs
lobbyList!!.map{ PacketRepository.send(ClearMinimapFlag::class.java, PlayerContext(it)) }
playersList!!.forEach(Player::tick)
renderablePlayers.forEach(Player::tick)
npcList!!.forEach(NPC::tick)
}
+16 -2
View File
@@ -11,18 +11,21 @@ import org.rs09.consts.Items
import rs09.ServerConstants
import rs09.game.content.global.shops.Shop
import rs09.game.content.global.shops.ShopItem
import rs09.game.system.SystemLogger
import rs09.game.system.config.ConfigParser
import rs09.game.system.config.ServerConfigParser
import rs09.game.world.GameWorld
import rs09.game.world.repository.Repository
import rs09.game.world.update.UpdateSequence
import java.nio.ByteBuffer
object TestUtils {
fun getMockPlayer(name: String, ironman: IronmanMode = IronmanMode.NONE): Player {
val p = Player(PlayerDetails(name))
p.details.session = MockSession()
val p = MockPlayer(name)
p.ironmanManager.mode = ironman
Repository.addPlayer(p)
//Update sequence has a separate list of players for some reason...
UpdateSequence.renderablePlayers.add(p)
return p
}
@@ -53,12 +56,23 @@ object TestUtils {
}
fun advanceTicks(amount: Int) {
SystemLogger.logInfo("Advancing ticks by $amount.")
for(i in 0 until amount) {
GameWorld.majorUpdateWorker.handleTickActions()
}
}
}
class MockPlayer(name: String) : Player(PlayerDetails(name)) {
init {
this.details.session = MockSession()
}
override fun update() {
//do nothing. This is for rendering stuff. We don't render a mock player. Not until the spaghetti is less spaghetti.
}
}
class MockSession : IoSession(null, null) {
val receivedPackets = ArrayList<Packet>()
var disconnected = false
@@ -0,0 +1,36 @@
package content
import TestUtils
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import rs09.game.world.GameWorld
class RandomEventManager {
companion object {init {
TestUtils.preTestSetup()
}}
@Test fun loginShouldEnableManager() {
val p = TestUtils.getMockPlayer("Bill")
rs09.game.content.ame.RandomEventManager().login(p)
val manager = rs09.game.content.ame.RandomEventManager.getInstance(p)
Assertions.assertNotNull(manager)
Assertions.assertEquals(true, manager!!.enabled)
}
@Test fun loginShouldSetNextSpawn() {
val p = TestUtils.getMockPlayer("Bill")
rs09.game.content.ame.RandomEventManager().login(p)
val manager = rs09.game.content.ame.RandomEventManager.getInstance(p)
Assertions.assertNotNull(manager)
Assertions.assertEquals(true, manager!!.nextSpawn > GameWorld.ticks)
}
@Test fun shouldSpawnRandomEventWithinMAXTICKSGivenNoRestrictions() {
val p = TestUtils.getMockPlayer("Bill")
p.setAttribute("tutorial:complete", true) //tutorial has to be complete to spawn randoms
rs09.game.content.ame.RandomEventManager().login(p)
TestUtils.advanceTicks(rs09.game.content.ame.RandomEventManager.MAX_DELAY_TICKS + 5)
Assertions.assertNotNull(p.getAttribute("re-npc", null))
}
}