Implemented 7 random events for Halloween, 17th October to 7th November

Includes server config options holiday_random_event and force_halloween_randoms
Admin command ::hrevent -p username -e eventName
Admin command ::forcehrevents holidayName
Admin command ::stophrevents
This commit is contained in:
Zerken
2023-09-28 08:31:21 +00:00
committed by Ryan
parent f6e83eb28f
commit dfdc9dc6a5
15 changed files with 826 additions and 0 deletions
+6
View File
@@ -311,5 +311,11 @@ class ServerConstants {
@JvmField
var NEW_PLAYER_ANNOUNCEMENT = true
@JvmField
var HOLIDAY_EVENT_RANDOMS = true
@JvmField
var FORCE_HALLOWEEN_RANDOMS = false
}
}
@@ -161,6 +161,8 @@ object ServerConfigParser {
ServerConstants.GRAFANA_TTL_DAYS = data.getLong("integrations.grafana_log_ttl_days", 7L).toInt()
ServerConstants.BETTER_DFS = data.getBoolean("world.better_dfs", true)
ServerConstants.NEW_PLAYER_ANNOUNCEMENT = data.getBoolean("world.new_player_announcement", true)
ServerConstants.HOLIDAY_EVENT_RANDOMS = data.getBoolean("world.holiday_event_randoms", true)
ServerConstants.FORCE_HALLOWEEN_RANDOMS = data.getBoolean("world.force_halloween_randoms", false)
val logLevel = data.getString("server.log_level", "VERBOSE").uppercase()
ServerConstants.LOG_LEVEL = parseEnumEntry<LogLevel>(logLevel) ?: LogLevel.VERBOSE
@@ -0,0 +1,86 @@
package core.game.worldevents.holiday
import core.api.*
import core.api.utils.WeightBasedTable
import core.game.interaction.MovementPulse
import core.game.node.entity.impl.PulseType
import core.game.node.entity.npc.NPC
import core.game.node.entity.player.Player
import core.game.world.map.Location
import core.game.world.map.RegionManager
import core.game.world.map.path.Pathfinder
import core.tools.secondsToTicks
import org.rs09.consts.Sounds
import kotlin.reflect.full.createInstance
abstract class HolidayRandomEventNPC(id:Int) : NPC(id) {
lateinit var player: Player
abstract var loot: WeightBasedTable?
var spawnLocation: Location? = null
var initialized = false
var finalized = false
var timerPaused = false
var ticksLeft = secondsToTicks(30)
open fun create(player: Player, loot: WeightBasedTable? = null, type: String = ""): HolidayRandomEventNPC {
val event = this::class.createInstance()
event.loot = loot
event.player = player
event.spawnLocation = RegionManager.getSpawnLocation(player, this)
return event
}
open fun terminate() {
pulseManager.clear(PulseType.STANDARD)
if (initialized && !finalized) {
poofClear(this)
playGlobalAudio(this.location, Sounds.SMOKEPUFF2_1931, 100)
}
finalized = true
}
open fun follow() {
pulseManager.run((object : MovementPulse(this, player, Pathfinder.DUMB) {
override fun pulse(): Boolean {
face(player)
return false
}
}), PulseType.STANDARD)
}
override fun tick() {
super.tick()
if (player.getAttribute<HolidayRandomEventNPC?>("holiday-npc", null) != this) {
terminate()
return
}
if (!player.getAttribute("holidayrandom:pause", false)) {
ticksLeft--
}
if (!pulseManager.hasPulseRunning() && !finalized) {
follow()
}
if (!player.isActive || !player.location.withinDistance(location, 10)) {
terminate()
}
if (ticksLeft <= 0 && initialized) {
terminate()
initialized = false
}
}
override fun init() {
initialized = true
finalized = false
timerPaused = false
spawnLocation ?: terminate()
location = spawnLocation
player.setAttribute("holiday-npc", this)
super.init()
}
override fun clear() {
super.clear()
if(player.getAttribute<HolidayRandomEventNPC?>("holiday-npc", null) == this) player.removeAttribute("holiday-npc")
}
}
@@ -0,0 +1,40 @@
package core.game.worldevents.holiday
import core.game.worldevents.holiday.halloween.randoms.*
enum class HolidayRandomEvents(val npc: HolidayRandomEventNPC, val type: String) {
BLACK_CAT(npc = BlackCatHolidayRandomNPC(), "halloween"),
SPIDER(npc = SpiderHolidayRandomNPC(), "halloween"),
GHOST(npc = GhostHolidayRandomNPC(), "halloween"),
ZOMBIE(npc = ZombieHolidayRandomNPC(), "halloween"),
WITCH(npc = WitchHolidayRandomNPC(), "halloween"),
DEATH(npc = DeathHolidayRandomNPC(), "halloween"),
VAMPIRE(npc = VampireHolidayRandomNPC(), "halloween");
companion object {
@JvmField
val halloweenEventsList = ArrayList<HolidayRandomEvents>()
val christmasEventsList = ArrayList<HolidayRandomEvents>()
init {
populateMappings()
}
fun getHolidayRandom(type: String): HolidayRandomEvents {
return when (type) {
"halloween" -> halloweenEventsList.random()
"christmas" -> christmasEventsList.random()
else -> throw Exception("Invalid event type!")
}
}
private fun populateMappings() {
for (event in values()) {
when(event.type) {
"halloween" -> halloweenEventsList.add(event)
"christmas" -> christmasEventsList.add(event)
}
}
}
}
}
@@ -0,0 +1,253 @@
package core.game.worldevents.holiday
import content.global.ame.RandomEventNPC
import content.global.skill.construction.HouseLocation
import core.ServerConstants
import core.api.*
import core.game.node.entity.Entity
import core.game.node.entity.player.Player
import core.game.system.command.Privilege
import core.game.system.timer.PersistTimer
import core.game.world.map.zone.ZoneRestriction
import core.game.world.repository.Repository
import core.tools.RandomFunction
import core.tools.colorize
import core.tools.minutesToTicks
import org.json.simple.JSONObject
import java.time.LocalDate
import java.time.Month
class HolidayRandoms() : PersistTimer(0, "holiday", isAuto = true), Commands {
var paused = false
var nextRandom: HolidayRandomEvents? = null
var currentHoliday: String? = null
val halloweenStartDate = LocalDate.of(LocalDate.now().year, Month.OCTOBER, 17)
val halloweenEndDate = LocalDate.of(LocalDate.now().year, Month.NOVEMBER, 7)
val christmasStartDate = LocalDate.of(LocalDate.now().year, Month.DECEMBER, 1)
val christmasEndDate = LocalDate.of(LocalDate.now().year, Month.DECEMBER, 31)
override fun run(entity: Entity): Boolean {
if (entity !is Player) return false
setNextExecution()
if (!canSpawn(entity)) {
delayNextExecution()
return true
}
val eventSelection = rollEventPool()
val eventNpc = eventSelection.npc.create(entity)
if (eventNpc.spawnLocation == null) {
entity.debug("[HolidayRandom] Attempted to spawn random, but spawnLoc was null.")
delayNextExecution()
return true
}
eventNpc.init()
setAttribute(entity, EVENT_NPC, eventNpc)
setAttribute(eventNpc, EVENT_NPC, eventNpc)
entity.debug("[HolidayRandom] Fired ${eventSelection.name}.")
return true
}
override fun onRegister(entity: Entity) {
if (entity !is Player || entity.isArtificial || !ServerConstants.HOLIDAY_EVENT_RANDOMS) {
entity.timers.removeTimer(this)
return
}
val player = entity.asPlayer()
when (checkIfHoliday()) {
"halloween" -> {
sendMessage(player, colorize("%OA chill goes down your spine..."))
currentHoliday = "halloween"
}
"none" -> player.timers.removeTimer(this)
}
if (runInterval == 0)
setNextExecution()
}
fun checkIfHoliday(): String {
val currentDate = LocalDate.now()
if ((!currentDate.isBefore(halloweenStartDate) && !currentDate.isAfter(halloweenEndDate)) || ServerConstants.FORCE_HALLOWEEN_RANDOMS)
return "halloween"
return "none"
}
override fun save(root: JSONObject, entity: Entity) {
root["ticksRemaining"] = (nextExecution - getWorldTicks()).toString()
}
override fun parse(root: JSONObject, entity: Entity) {
runInterval = (root["ticksRemaining"]?.toString()?.toIntOrNull() ?: 0)
nextExecution = getWorldTicks() + runInterval
}
private fun canSpawn(entity: Entity) : Boolean {
if (entity.zoneMonitor.isRestricted(ZoneRestriction.RANDOM_EVENTS) || getAttribute<RandomEventNPC?>(entity, "re-npc", null) != null)
return false
val current = getAttribute<HolidayRandomEventNPC?>(entity, EVENT_NPC, null)
if (current != null)
return false
if (paused || entity.inCombat())
return false
return true
}
private fun delayNextExecution() {
runInterval = 50
nextExecution = getWorldTicks() + runInterval
}
private fun setNextExecution() {
runInterval = RandomFunction.random(MIN_DELAY_TICKS, MAX_DELAY_TICKS + 1)
nextExecution = getWorldTicks() + runInterval
}
private fun rollEventPool() : HolidayRandomEvents {
if (nextRandom != null) {
val result = nextRandom!!
nextRandom = null
return result
}
return when (currentHoliday) {
"halloween" -> HolidayRandomEvents.getHolidayRandom("halloween")
else -> HolidayRandomEvents.SPIDER
}
}
override fun defineCommands() {
define("hrevent", Privilege.ADMIN, "::hrevent [-p] <lt>player name<gt> [-e <lt>event name<gt>]", "Spawns a holiday random event for the target player.<br>Optional -e parameter to pass a specific event.") { player, args ->
if (args.size == 1) {
val possible = HolidayRandomEvents.values()
for (event in possible) {
notify(player, event.name.lowercase())
}
return@define
}
val arg = parseCommandArgs(args.joinToString(" "))
val target = Repository.getPlayerByName(arg.targetPlayer)
if (getTimer<HolidayRandoms>(player) == null)
reject(player, "No holiday random events are active. To force a holiday's random events use ::forcehrevents")
if (target == null)
reject(player, "Unable to find user ${arg.targetPlayer}.")
forceEvent(target!!, arg.targetEvent)
}
define("forcehrevents", Privilege.ADMIN, "::forcehrevents [eventname]", "Force enable holiday random events.") { player, args ->
if (args.size == 1) {
notify(player, "Holidays: halloween")
return@define
}
val event = args[1]
if (checkIfHoliday() != "none")
reject(player, "Holiday randoms are already enabled: ${checkIfHoliday()}. Use ::stophrevents first.")
ServerConstants.HOLIDAY_EVENT_RANDOMS = true
when (event) {
"halloween" -> {
ServerConstants.FORCE_HALLOWEEN_RANDOMS = true
for (p in Repository.players) {
if (getTimer<HolidayRandoms>(p) != null || p.isArtificial) {
continue
}
notify(p, colorize("%RHalloween Randoms are now enabled!"))
registerTimer(p, HolidayRandoms())
}
}
else -> reject(player, "Invalid event!")
}
}
define("stophrevents", Privilege.ADMIN, "::stophrevents", "Stops all holiday random events.") { player, _ ->
if (checkIfHoliday() == "none")
reject(player, "No holiday random events are currently active.")
ServerConstants.HOLIDAY_EVENT_RANDOMS = false
ServerConstants.FORCE_HALLOWEEN_RANDOMS = false
for (p in Repository.players) {
if (getTimer<HolidayRandoms>(p) == null) {
continue
}
removeHolidayTimer(p)
notify(p, "Holiday random events are now disabled!")
}
}
}
data class CommandArgs (val targetPlayer: String, val targetEvent: HolidayRandomEvents?)
companion object {
const val EVENT_NPC = "holiday-npc"
val MIN_DELAY_TICKS = minutesToTicks(30)
val MAX_DELAY_TICKS = minutesToTicks(90)
fun terminateEventNpc (player: Player) {
getEventNpc(player)?.terminate()
}
fun getEventNpc (player: Player) : HolidayRandomEventNPC? {
return getAttribute<HolidayRandomEventNPC?>(player, EVENT_NPC, null)
}
fun pause (player: Player) {
val timer = getTimer<HolidayRandoms>(player) ?: return
timer.paused = true
}
fun unpause (player: Player) {
val timer = getTimer<HolidayRandoms>(player) ?: return
timer.paused = false
}
fun removeHolidayTimer (player: Player) {
val timer = getTimer<HolidayRandoms>(player) ?: return
removeTimer(player, timer)
}
fun forceEvent (player: Player, event: HolidayRandomEvents? = null) {
val timer = getTimer<HolidayRandoms>(player) ?: return
timer.nextExecution = getWorldTicks()
timer.nextRandom = event
}
fun parseCommandArgs (args: String, commandName: String = "hrevent") : CommandArgs {
val tokens = args.split(" ")
val modeTokens = arrayOf("-p", "-e")
var userString = ""
var eventString = ""
var lastMode = "-p"
for (token in tokens) {
when (token) {
commandName -> continue
in modeTokens -> lastMode = token
else -> when (lastMode) {
"-p" -> userString += "$token "
"-e" -> eventString += "$token "
}
}
}
val username = userString.trim().lowercase().replace(" ", "_")
val eventName = eventString.trim().uppercase().replace(" ", "_")
var event: HolidayRandomEvents? = null
try { event = HolidayRandomEvents.valueOf(eventName) } catch (_: Exception) {}
return CommandArgs(username, event)
}
}
}
@@ -0,0 +1,23 @@
package core.game.worldevents.holiday
import core.api.playAudio
import core.api.sendMessage
import core.api.visualize
import core.game.node.entity.Entity
import core.game.node.entity.player.Player
import core.game.system.timer.RSTimer
import core.tools.minutesToTicks
import core.tools.secondsToTicks
import org.rs09.consts.Sounds
class ResetHolidayAppearance() : RSTimer(minutesToTicks(1), "reset-holiday-appearance") {
override fun run(entity: Entity): Boolean {
if (entity is Player) {
entity.asPlayer().appearance.transformNPC(-1)
playAudio(entity.asPlayer(), Sounds.WEAKEN_HIT_3010)
visualize(entity, -1, 86)
}
entity.timers.removeTimer(this)
return true
}
}
@@ -0,0 +1,28 @@
package core.game.worldevents.holiday.halloween.randoms
import core.api.*
import core.api.utils.WeightBasedTable
import core.game.interaction.QueueStrength
import core.game.node.entity.combat.ImpactHandler.HitsplatType
import core.game.worldevents.holiday.HolidayRandomEventNPC
import core.game.worldevents.holiday.HolidayRandoms
import org.rs09.consts.Sounds
class BlackCatHolidayRandomNPC(override var loot: WeightBasedTable? = null) : HolidayRandomEventNPC(4607) {
override fun init() {
super.init()
queueScript(this, 8, QueueStrength.SOFT) {
playGlobalAudio(this.location, Sounds.CAT_ATTACK_333)
sendChat("HISS")
if (player.location.withinDistance(this.location, 3)) {
this.face(player)
sendMessage(player, "The cat scratches you and runs away.")
val hit = if (player.skills.lifepoints < 5) 0 else 1
impact(player, hit, HitsplatType.NORMAL)
}
HolidayRandoms.terminateEventNpc(player)
return@queueScript stopExecuting(this)
}
}
}
@@ -0,0 +1,39 @@
package core.game.worldevents.holiday.halloween.randoms
import core.api.*
import core.api.utils.WeightBasedTable
import core.game.interaction.QueueStrength
import core.game.worldevents.holiday.HolidayRandomEventNPC
import core.game.worldevents.holiday.HolidayRandoms
import core.tools.RandomFunction
import org.rs09.consts.Sounds
class DeathHolidayRandomNPC(override var loot: WeightBasedTable? = null) : HolidayRandomEventNPC(2862) {
override fun init() {
super.init()
playJingle(player, 337)
queueScript(this, 6, QueueStrength.SOFT) { stage: Int ->
when (stage) {
0 -> {
this.face(player)
visualize(this, 864, -1)
playGlobalAudio(this.location, Sounds.ZOMBIE_MOAN_2324)
return@queueScript delayScript(this, 1)
}
1 -> {
when(RandomFunction.getRandom(2)) {
0 -> sendChat(this, "Your end is near, ${player.name.capitalize()}...")
1 -> sendChat(this, "Time is running out, ${player.name.capitalize()}...")
2 -> sendChat(this, "Tick tock, ${player.name.capitalize()}...")
}
return@queueScript delayScript(this, 4)
}
2 -> {
HolidayRandoms.terminateEventNpc(player)
return@queueScript stopExecuting(this)
}
else -> return@queueScript stopExecuting(this)
}
}
}
}
@@ -0,0 +1,24 @@
package core.game.worldevents.holiday.halloween.randoms
import core.api.*
import core.api.utils.WeightBasedTable
import core.game.worldevents.holiday.HolidayRandomEventNPC
import core.tools.RandomFunction
import org.rs09.consts.Sounds
class GhostHolidayRandomNPC(override var loot: WeightBasedTable? = null) : HolidayRandomEventNPC(2716) {
override fun init() {
super.init()
this.isAggressive = false
playGlobalAudio(this.location, Sounds.BIGGHOST_APPEAR_1595)
animate(player, 2836)
sendChat(this, "WooooOOOooOOo")
sendMessage(player, "The air suddenly gets colder...")
}
override fun tick() {
super.tick()
if (RandomFunction.roll(10))
playGlobalAudio(this.location, Sounds.BIGGHOST_LAUGH_1600)
}
}
@@ -0,0 +1,22 @@
package core.game.worldevents.holiday.halloween.randoms
import core.api.getAttribute
import core.api.playGlobalAudio
import core.game.node.entity.Entity
import core.game.node.entity.combat.CombatStyle
import core.game.node.entity.npc.NPC
import core.game.node.entity.npc.NPCBehavior
import core.game.worldevents.holiday.HolidayRandomEventNPC
import org.rs09.consts.Sounds
class SpiderHolidayRandomBehavior : NPCBehavior() {
override fun canBeAttackedBy(self: NPC, attacker: Entity, style: CombatStyle, shouldSendMessage: Boolean): Boolean {
return false
}
override fun onDeathStarted(self: NPC, killer: Entity) {
getAttribute<HolidayRandomEventNPC?>(self, "holiday-npc", null)?.terminate()
playGlobalAudio(self.location, Sounds.SMALL_SPIDER_DEATH_3608)
super.onDeathFinished(self, killer)
}
}
@@ -0,0 +1,47 @@
package core.game.worldevents.holiday.halloween.randoms
import core.api.*
import core.api.utils.WeightBasedTable
import core.game.interaction.QueueStrength
import core.game.node.entity.combat.ImpactHandler
import core.game.world.update.flag.context.Animation
import core.game.worldevents.holiday.HolidayRandomEventNPC
import core.game.worldevents.holiday.HolidayRandoms
import org.rs09.consts.Sounds
class SpiderHolidayRandomNPC(override var loot: WeightBasedTable? = null) : HolidayRandomEventNPC(61) {
override fun init() {
super.init()
this.behavior = SpiderHolidayRandomBehavior()
playGlobalAudio(this.location, Sounds.SPIDER_4375)
var stomped = false
queueScript(this,4, QueueStrength.SOFT) { stage: Int ->
when (stage) {
0 -> {
sendChat(player, "Eww a spider!")
return@queueScript delayScript(this, 2)
}
1 -> {
if (player.location.withinDistance(this.location, 3)) {
player.animate(Animation(4278))
playGlobalAudio(this.location, Sounds.UNARMED_KICK_2565)
sendMessage(player, "You stomp the spider.")
stomped = true
}
return@queueScript delayScript(this, 1)
}
2 -> {
if (stomped) {
impact(this, 1, ImpactHandler.HitsplatType.NORMAL)
} else {
sendMessage(player, "The spider runs away.")
playGlobalAudio(this.location, Sounds.SPIDER_4375)
HolidayRandoms.terminateEventNpc(player)
}
return@queueScript stopExecuting(this)
}
else -> return@queueScript stopExecuting(this)
}
}
}
}
@@ -0,0 +1,46 @@
package core.game.worldevents.holiday.halloween.randoms
import core.api.*
import core.api.utils.WeightBasedTable
import core.game.interaction.QueueStrength
import core.game.node.entity.combat.ImpactHandler
import core.game.worldevents.holiday.HolidayRandomEventNPC
import core.game.worldevents.holiday.HolidayRandoms
import core.game.worldevents.holiday.ResetHolidayAppearance
import core.tools.RandomFunction
import core.tools.colorize
import org.rs09.consts.Sounds
class VampireHolidayRandomNPC(override var loot: WeightBasedTable? = null) : HolidayRandomEventNPC(1023) {
override fun init() {
super.init()
playGlobalAudio(this.location, Sounds.REGULAR_VAMPIRE_APPEAR_1897)
visualize(this, -1 , 1863)
queueScript(this, 3, QueueStrength.SOFT) { stage: Int ->
when (stage) {
0 -> {
this.face(player)
visualize(this, 7183 , -1)
playGlobalAudio(this.location, Sounds.VAMPIRE_ATTACK_879)
if (RandomFunction.roll(2)) {
player.timers.registerTimer(ResetHolidayAppearance())
sendMessage(player, colorize("%RThe vampire bites your neck!"))
val hit = if (player.skills.lifepoints < 5) 0 else 2
impact(player, hit, ImpactHandler.HitsplatType.NORMAL)
player.appearance.transformNPC(1023)
} else {
sendMessage(player, "The vampire tries to bite your neck and misses!")
impact(player, 0, ImpactHandler.HitsplatType.NORMAL)
}
return@queueScript delayScript(this, 8)
}
1 -> {
visualize(this, 10530, 1863)
HolidayRandoms.terminateEventNpc(player)
return@queueScript stopExecuting(this)
}
else -> return@queueScript stopExecuting(this)
}
}
}
}
@@ -0,0 +1,149 @@
package core.game.worldevents.holiday.halloween.randoms
import core.api.*
import core.api.utils.WeightBasedTable
import core.game.interaction.QueueStrength
import core.game.node.entity.combat.ImpactHandler
import core.game.worldevents.holiday.ResetHolidayAppearance
import core.game.worldevents.holiday.HolidayRandomEventNPC
import core.game.worldevents.holiday.HolidayRandoms
import core.tools.RandomFunction
import org.rs09.consts.Sounds
class WitchHolidayRandomNPC(override var loot: WeightBasedTable? = null) : HolidayRandomEventNPC(611) {
override fun init() {
super.init()
when (RandomFunction.getRandom(4)) {
0 -> {
queueScript(this, 6, QueueStrength.SOFT) { stage: Int ->
when (stage) {
0 -> {
sendChat(this, "Brackium Emendo!")
this.face(player)
playGlobalAudio(this.location, Sounds.CONFUSE_CAST_AND_FIRE_119)
animate(this, 1978)
spawnProjectile(this, player, 109)
return@queueScript delayScript(this, 2)
}
1 -> {
player.appearance.transformNPC(3138)
playAudio(player, Sounds.SKELETON_RESURRECT_1687)
registerTimer(player, ResetHolidayAppearance())
return@queueScript delayScript(this, 4)
}
2 -> {
sendChat(this, "That was not right...")
visualize(this, 857, -1)
HolidayRandoms.terminateEventNpc(player)
return@queueScript stopExecuting(this)
}
else -> return@queueScript stopExecuting(this)
}
}
}
1 -> {
queueScript(this, 6, QueueStrength.SOFT) { stage: Int ->
when (stage) {
0 -> {
sendChat(this, "Bombarda!")
this.face(player)
playGlobalAudio(this.location, Sounds.CURSE_CAST_AND_FIRE_127)
animate(this, 1978)
spawnProjectile(this, player, 109)
return@queueScript delayScript(this, 2)
}
1 -> {
playGlobalAudio(player.location, Sounds.EXPLOSION_1487)
visualize(player, -1, 659)
val hit = if (player.skills.lifepoints < 5) 0 else 2
impact(player, hit, ImpactHandler.HitsplatType.NORMAL)
return@queueScript delayScript(this, 2)
}
2 -> {
HolidayRandoms.terminateEventNpc(player)
return@queueScript stopExecuting(this)
}
else -> return@queueScript stopExecuting(this)
}
}
}
2 -> {
queueScript(this, 6, QueueStrength.SOFT) {stage: Int ->
when (stage) {
0 -> {
sendChat(this, "Tarantallegra!")
this.face(player)
playGlobalAudio(this.location, Sounds.WEAKEN_CAST_AND_FIRE_3011)
animate(this, 1978)
spawnProjectile(this, player, 109)
return@queueScript delayScript(this, 2)
}
1 -> {
animate(player, 3543, true)
sendMessage(player, "You suddenly burst into dance.")
return@queueScript delayScript(this, 2)
}
2 -> {
visualize(this, 861, -1)
playGlobalAudio(this.location, Sounds.HUMAN_LAUGH_1_3071)
HolidayRandoms.terminateEventNpc(player)
return@queueScript stopExecuting(this)
}
else -> return@queueScript stopExecuting(this)
}
}
}
3 -> {
queueScript(this, 6, QueueStrength.SOFT) {stage: Int ->
when (stage) {
0 -> {
sendChat(this, "Vespertilio!")
this.face(player)
playGlobalAudio(this.location, Sounds.WEAKEN_CAST_AND_FIRE_3011)
animate(this, 1978)
spawnProjectile(this, player, 109)
return@queueScript delayScript(this, 2)
}
1 -> {
visualize(player, 10530, 1863)
playGlobalAudio(player.location, Sounds.VAMPIRE_SUMMON_1899)
return@queueScript delayScript(this, 4)
}
2 -> {
player.appearance.transformNPC(6835)
HolidayRandoms.terminateEventNpc(player)
registerTimer(player, ResetHolidayAppearance())
return@queueScript stopExecuting(this)
}
else -> return@queueScript stopExecuting(this)
}
}
}
4 -> {
queueScript(this, 6, QueueStrength.SOFT) {stage: Int ->
when (stage) {
0 -> {
sendChat(this, "Sella!")
this.face(player)
playGlobalAudio(this.location, Sounds.WEAKEN_CAST_AND_FIRE_3011)
animate(this, 1978)
spawnProjectile(this, player, 109)
return@queueScript delayScript(this, 2)
}
1 -> {
player.appearance.transformNPC(3293)
playGlobalAudio(player.location, Sounds.KR_JUDGE_HAMMER_3822)
registerTimer(player, ResetHolidayAppearance())
return@queueScript delayScript(this, 4)
}
2 -> {
HolidayRandoms.terminateEventNpc(player)
return@queueScript stopExecuting(this)
}
else -> return@queueScript stopExecuting(this)
}
}
}
}
}
}
@@ -0,0 +1,57 @@
package core.game.worldevents.holiday.halloween.randoms
import core.api.*
import core.api.utils.WeightBasedTable
import core.game.interaction.QueueStrength
import core.game.node.entity.combat.ImpactHandler
import core.game.worldevents.holiday.ResetHolidayAppearance
import core.game.worldevents.holiday.HolidayRandomEventNPC
import core.game.worldevents.holiday.HolidayRandoms
import core.tools.RandomFunction
import core.tools.colorize
import org.rs09.consts.Sounds
class ZombieHolidayRandomNPC(override var loot: WeightBasedTable? = null) : HolidayRandomEventNPC(2714) {
override fun init() {
super.init()
this.isAggressive = false
playGlobalAudio(this.location, Sounds.ZOMBIE_DEATH_922)
playJingle(player, 314)
sendMessage(player, "A zombie crawls out of the ground beneath you...")
animate(player, 7272)
queueScript(this, 2, QueueStrength.SOFT) { stage: Int ->
when (stage) {
0 -> {
when (RandomFunction.getRandom(2)) {
0 -> sendChat(this, "Brainnnss!")
1 -> sendChat(this, "RArrgghhh")
2 -> sendChat(this, "Flesshhh")
}
return@queueScript delayScript(this, 1)
}
1 -> {
this.face(player)
visualize(this, 5568 , -1)
playGlobalAudio(this.location, Sounds.ZOMBIE_ATTACK_918)
if (RandomFunction.roll(2)) {
player.timers.registerTimer(ResetHolidayAppearance())
sendMessage(player, colorize("%RThe zombie bites you!"))
val hit = if (player.skills.lifepoints < 5) 0 else 2
impact(player, hit, ImpactHandler.HitsplatType.NORMAL)
player.appearance.transformNPC(2866)
} else {
impact(player, 0, ImpactHandler.HitsplatType.NORMAL)
sendMessage(player, "The zombie tries to bite you and misses!")
}
return@queueScript delayScript(this, 8)
}
2 -> {
animate(this, 5575)
HolidayRandoms.terminateEventNpc(player)
return@queueScript stopExecuting(this)
}
else -> return@queueScript stopExecuting(this)
}
}
}
}
+4
View File
@@ -97,6 +97,10 @@ better_agility_pyramid_gp = true
better_dfs = true
#new player announcement
new_player_announcement = true
#enables holiday random events (no effect on normal random events)
holiday_event_randoms = true
#force holiday randoms (can only force one at a time)
force_halloween_randoms = false
[paths]
#path to the data folder, which contains the cache subfolder and such