Implemented 7 Christmas Holiday randoms:

Snowman
Snowman Fight
Santa
Jack Frost
Choir
Snowstorm
Cook
This commit is contained in:
Zerken 2023-11-11 03:49:04 +00:00 committed by Ryan
parent 8ef5d8bce4
commit cd4d0ec20b
31 changed files with 678 additions and 38 deletions

View file

@ -60583,22 +60583,30 @@
"attack_level": "1"
},
{
"examine": "A snowman in fake dragon armour.",
"combat_audio": "29,3295,3287",
"melee_animation": "7558",
"defence_animation": "7559",
"death_animation": "7560",
"name": "Dragon snowman",
"defence_level": "1",
"safespot": null,
"lifepoints": "10",
"combat_audio": "408,410,409",
"lifepoints": "20",
"strength_level": "1",
"id": "6743",
"range_level": "1",
"attack_level": "1"
},
{
"examine": "Arr!",
"combat_audio": "29,3295,3287",
"melee_animation": "7558",
"defence_animation": "7559",
"death_animation": "7560",
"name": "Pirate snowman",
"defence_level": "1",
"safespot": null,
"lifepoints": "10",
"combat_audio": "703,705,704",
"lifepoints": "20",
"strength_level": "1",
"id": "6745",
"range_level": "1",
@ -72440,5 +72448,28 @@
"examine": "A very strange plant.",
"name": "Strange Plant",
"id": "407"
},
{
"agg_radius": "",
"examine": "A helmetted, barbarian snowman.",
"death_animation": "7560",
"name": "Barbarian Snowman",
"defence_level": "1",
"melee_animation": "7565",
"lifepoints": "20",
"combat_audio": "12,3295,3287",
"id": "6742",
"defence_animation": "7559"
},
{
"examine": "A snow dwarf.",
"death_animation": "7560",
"name": "Dwarf Snowman",
"defence_level": "1",
"melee_animation": "7565",
"lifepoints": "20",
"combat_audio": "12,3295,3287",
"id": "6744",
"defence_animation": "7559"
}
]

View file

@ -5,9 +5,13 @@ import content.region.kandarin.barcrawl.BarcrawlManager
import content.region.kandarin.barcrawl.BarcrawlType
import content.global.ame.RandomEvents
import content.minigame.gnomecooking.*
import core.api.getAttribute
import core.game.interaction.InteractionListener
import core.game.interaction.IntType
import core.game.system.timer.impl.AntiMacro
import core.game.worldevents.holiday.HolidayRandomEventNPC
import core.game.worldevents.holiday.HolidayRandomEvents
import core.game.worldevents.holiday.HolidayRandoms
/**
* Handles the NPC talk-to option.
@ -39,6 +43,18 @@ class NPCTalkListener : InteractionListener {
}
return@on true
}
if (HolidayRandomEvents.holidayRandomIDs.contains(node.id) && node is HolidayRandomEventNPC) {
if(HolidayRandoms.getEventNpc(player) == null || HolidayRandoms.getEventNpc(player) != node.asNpc() || HolidayRandoms.getEventNpc(player)?.finalized == true) {
player.sendMessage("They aren't interested in talking to you.")
} else {
HolidayRandoms.getEventNpc(player)?.talkTo(node.asNpc())
}
return@on true
}
if (getAttribute(npc, "holiday_random_extra_npc", false) && HolidayRandoms.getEventNpc(player) != null) {
HolidayRandoms.getEventNpc(player)?.talkTo(node.asNpc())
return@on true
}
if (!npc.getAttribute("facing_booth", false)) {
npc.faceLocation(player.location)
}

View file

@ -318,6 +318,9 @@ class ServerConstants {
@JvmField
var FORCE_HALLOWEEN_RANDOMS = false
@JvmField
var FORCE_CHRISTMAS_RANDOMS = false
@JvmField
var RUNECRAFTING_FORMULA_REVISION = 581
}

View file

@ -778,8 +778,13 @@ fun sendMessage(player: Player, message: String) {
* @param entity the entity to send the chat for
* @param message the message to display
*/
fun sendChat(entity: Entity, message: String) {
fun sendChat(entity: Entity, message: String, delay: Int = -1) {
if (delay > -1) {
queueScript(entity, delay, QueueStrength.SOFT) {
entity.sendChat(message)
return@queueScript stopExecuting(entity)
}
} else entity.sendChat(message)
}
/**

View file

@ -444,7 +444,7 @@ class CombatPulse(
if (entity is NPC)
entity.asNpc().behavior.beforeAttackFinalized(entity, victim, state)
if (impact || getDelay() == 0) {
if (state.estimatedHit != 0 && victim is NPC && entity is Player) {
if (state.estimatedHit != 0 && victim is NPC) {
val n = victim.asNpc()
val audio = n.getAudio(1)
if (audio != null) {

View file

@ -364,7 +364,7 @@ abstract class CombatSwingHandler(var type: CombatStyle?) {
//plays a punching sound when no weapon is equipped
playGlobalAudio(entity.location, Sounds.HUMAN_ATTACK_2564)
}
} else if (entity is NPC && victim is Player) {
} else if (entity is NPC) {
val npc = entity.asNpc()
val audio = npc.getAudio(0)
if (audio != null) playGlobalAudio(entity.location, audio.id)

View file

@ -49,14 +49,11 @@ public final class DeathTask extends NodeTask {
Entity killer = n.length > 0 ? (Entity) n[0] : e;
if (e instanceof NPC) {
killer.removeAttribute("combat-time");
if (killer instanceof Player) {
Player p = killer.asPlayer();
Audio audio = e.asNpc().getAudio(2);
if (audio != null) {
playGlobalAudio(e.getLocation(), audio.id);
}
}
}
e.graphics(Animator.RESET_G);
e.visualize(e.getProperties().getDeathAnimation(), e.getProperties().deathGfx);
e.getAnimator().forceAnimation(e.getProperties().getDeathAnimation());

View file

@ -163,6 +163,7 @@ object ServerConfigParser {
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)
ServerConstants.FORCE_CHRISTMAS_RANDOMS = data.getBoolean("world.force_christmas_randoms", false)
ServerConstants.RUNECRAFTING_FORMULA_REVISION = data.getLong("world.runecrafting_formula_revision", 581).toInt()
val logLevel = data.getString("server.log_level", "VERBOSE").uppercase()

View file

@ -1,7 +1,6 @@
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
@ -15,16 +14,14 @@ 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 {
open fun create(player: Player, type: String = ""): HolidayRandomEventNPC {
val event = this::class.createInstance()
event.loot = loot
event.player = player
event.spawnLocation = RegionManager.getSpawnLocation(player, this)
return event
@ -83,4 +80,6 @@ abstract class HolidayRandomEventNPC(id:Int) : NPC(id) {
super.clear()
if(player.getAttribute<HolidayRandomEventNPC?>("holiday-npc", null) == this) player.removeAttribute("holiday-npc")
}
abstract fun talkTo(npc: NPC)
}

View file

@ -1,5 +1,6 @@
package core.game.worldevents.holiday
import core.game.worldevents.holiday.christmas.randoms.*
import core.game.worldevents.holiday.halloween.randoms.*
enum class HolidayRandomEvents(val npc: HolidayRandomEventNPC, val type: String) {
@ -9,12 +10,20 @@ enum class HolidayRandomEvents(val npc: HolidayRandomEventNPC, val type: String)
ZOMBIE(npc = ZombieHolidayRandomNPC(), "halloween"),
WITCH(npc = WitchHolidayRandomNPC(), "halloween"),
DEATH(npc = DeathHolidayRandomNPC(), "halloween"),
VAMPIRE(npc = VampireHolidayRandomNPC(), "halloween");
VAMPIRE(npc = VampireHolidayRandomNPC(), "halloween"),
CHOIR(npc = ChoirHolidayRandomNPC(), "christmas"),
SANTA(npc = SantaHolidayRandomNPC(), "christmas"),
SNOWMAN_FIGHT(npc = SnowmanFightHolidayRandom(), "christmas"),
JACK_FROST(npc = JackFrostHolidayRandomNPC(), "christmas"),
SNOWMAN(npc = SnowmanHolidayRandomNPC(), "christmas"),
SNOWSTORM(npc = SnowStormHolidayRandomNPC(), "christmas"),
COOK(npc = CookHolidayRandomNPC(), "christmas");
companion object {
@JvmField
val halloweenEventsList = ArrayList<HolidayRandomEvents>()
val christmasEventsList = ArrayList<HolidayRandomEvents>()
val holidayRandomIDs = HolidayRandomEvents.values().map { it.npc.id }.toList()
init {
populateMappings()

View file

@ -1,7 +1,6 @@
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
@ -63,6 +62,10 @@ class HolidayRandoms() : PersistTimer(0, "holiday", isAuto = true), Commands {
sendMessage(player, colorize("%OA chill goes down your spine..."))
currentHoliday = "halloween"
}
"christmas" -> {
sendMessage(player, colorize("%GHappy Holidays."))
currentHoliday = "christmas"
}
"none" -> player.timers.removeTimer(this)
}
@ -75,6 +78,9 @@ class HolidayRandoms() : PersistTimer(0, "holiday", isAuto = true), Commands {
if ((!currentDate.isBefore(halloweenStartDate) && !currentDate.isAfter(halloweenEndDate)) || ServerConstants.FORCE_HALLOWEEN_RANDOMS)
return "halloween"
if ((!currentDate.isBefore(christmasStartDate) && !currentDate.isAfter(christmasEndDate)) || ServerConstants.FORCE_CHRISTMAS_RANDOMS)
return "christmas"
return "none"
}
@ -120,7 +126,8 @@ class HolidayRandoms() : PersistTimer(0, "holiday", isAuto = true), Commands {
}
return when (currentHoliday) {
"halloween" -> HolidayRandomEvents.getHolidayRandom("halloween")
else -> HolidayRandomEvents.SPIDER
"christmas" -> HolidayRandomEvents.getHolidayRandom("christmas")
else -> throw Exception("Invalid event type!")
}
}
@ -148,7 +155,7 @@ class HolidayRandoms() : PersistTimer(0, "holiday", isAuto = true), Commands {
define("forcehrevents", Privilege.ADMIN, "::forcehrevents [eventname]", "Force enable holiday random events.") { player, args ->
if (args.size == 1) {
notify(player, "Holidays: halloween")
notify(player, "Holidays: halloween, christmas")
return@define
}
val event = args[1]
@ -166,15 +173,26 @@ class HolidayRandoms() : PersistTimer(0, "holiday", isAuto = true), Commands {
registerTimer(p, HolidayRandoms())
}
}
"christmas" -> {
ServerConstants.FORCE_CHRISTMAS_RANDOMS = true
for (p in Repository.players) {
if (getTimer<HolidayRandoms>(p) != null || p.isArtificial) {
continue
}
notify(p, colorize("%GChristmas 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")
if (checkIfHoliday() == "none" || !ServerConstants.HOLIDAY_EVENT_RANDOMS)
reject(player, "No holiday random events are currently active.")
ServerConstants.HOLIDAY_EVENT_RANDOMS = false
ServerConstants.FORCE_HALLOWEEN_RANDOMS = false
ServerConstants.FORCE_CHRISTMAS_RANDOMS = false
for (p in Repository.players) {
if (getTimer<HolidayRandoms>(p) == null) {
continue

View file

@ -123,7 +123,7 @@ class Giftmas : Commands, StartupListener, LoginListener, InteractionListener {
private val MESSAGE_DAILYXP_REACHED_SKILLING = colorize("%RYou have reached your daily limit of presents from skilling!")
private val MESSAGE_DAILYXP_REACHED_COMBAT = colorize("%RYou have reached your daily limit of presents from combat!")
private val MESSAGE_PRESENT_GRANTED = colorize("%GYou find a present while training!")
private val MBOX_LOOT = WeightBasedTable.create(
val MBOX_LOOT = WeightBasedTable.create(
WeightedItem(Items.TOY_HORSEY_2520, 1, 1, 0.025),
WeightedItem(Items.TOY_HORSEY_2522, 1, 1, 0.025),
WeightedItem(Items.TOY_HORSEY_2524, 1, 1, 0.025),

View file

@ -0,0 +1,63 @@
package core.game.worldevents.holiday.christmas.randoms
import core.api.*
import core.game.interaction.QueueStrength
import core.game.node.entity.npc.NPC
import core.game.worldevents.holiday.HolidayRandomEventNPC
import core.tools.RandomFunction
import org.rs09.consts.NPCs
class ChoirHolidayRandomNPC() : HolidayRandomEventNPC(NPCs.ZANARIS_CHOIR_3312) {
override fun init() {
super.init()
queueScript(this, 4, QueueStrength.SOFT) { stage: Int ->
when (stage) {
0 -> {
face(player)
when (RandomFunction.getRandom(3)) {
0 -> {
sendChat(this, "Jingle bells, jingle bells!")
sendChat(this, "Jingle all the way!", 4)
sendChat(this, "Oh what fun it is to ride", 8)
sendChat(this, "On a one unicorn open sleigh", 12)
sendChat(this, "HEY!", 15)
return@queueScript delayScript(this, 16)
}
1 -> {
sendChat(this, "Silver bells")
sendChat(this, "Silver bells", 5)
sendChat(this, "It's Christmas time in the city", 10)
sendChat(this, "Ring a ling", 15)
sendChat(this, "Hear them ring", 20)
sendChat(this, "Soon it will be Christmas day", 25)
return@queueScript delayScript(this, 26)
}
2 -> {
sendChat(this, "Deck the halls with boughs of ranarr")
sendChat(this, "Fa la la la la la la la!", 5)
sendChat(this, "Tis the season to be jolly", 10)
sendChat(this, "Fa la la la la la la la!", 15)
return@queueScript delayScript(this, 16)
}
3 -> {
sendChat(this, "O Wintumber Tree, O Wintumber tree,")
sendChat(this, "How lovely are your branches!", 5)
sendChat(this, "O Wintumber Tree, O Wintumber tree,", 10)
sendChat(this, "Of all the trees most lovely", 15)
return@queueScript delayScript(this, 16)
}
else -> return@queueScript keepRunning(this)
}
}
1 -> {
terminate()
return@queueScript stopExecuting(this)
}
else -> return@queueScript stopExecuting(this)
}
}
}
override fun talkTo(npc: NPC) {
}
}

View file

@ -0,0 +1,50 @@
package core.game.worldevents.holiday.christmas.randoms
import core.api.addItemOrDrop
import core.game.dialogue.DialogueFile
import core.game.dialogue.FacialExpression
import core.game.worldevents.holiday.HolidayRandoms
import org.rs09.consts.Items
class CookHolidayRandomDialogue : DialogueFile() {
private val cakes = listOf(Items.CAKE_1891, Items.CHOCOLATE_CAKE_1897, Items.MINT_CAKE_9475)
override fun handle(componentID: Int, buttonID: Int) {
if (HolidayRandoms.getEventNpc(player!!) == null)
player!!.dialogueInterpreter.close()
when (stage) {
0 -> npcl(FacialExpression.HAPPY, "Greetings, ${player!!.username.capitalize()}. Every year around christmas I give away cake to the community. Would you care for a fresh baked cake?").also { stage++ }
1 -> options("Sure, I will take a cake.", "Why are you giving cakes away?", "No, thanks.").also { stage++ }
2 -> when (buttonID) {
1 -> playerl(FacialExpression.HAPPY, "Sure, I will take a cake.").also { stage = 40 }
2 -> playerl(FacialExpression.HALF_ASKING, "Why are you giving away cakes?").also { stage = 20 }
3 -> playerl(FacialExpression.NEUTRAL, "No, thanks.").also { stage = 10 }
}
10 -> npcl(FacialExpression.HAPPY, "Okay, I will find someone else who wants it. Merry Christmas, ${player!!.username.capitalize()}.").also { stage++ }
11 -> {
HolidayRandoms.terminateEventNpc(player!!)
end()
}
20 -> npcl(FacialExpression.NEUTRAL, "It's just something I do this time of year... Errr... well...").also { stage++ }
21 -> playerl(FacialExpression.HALF_ASKING, "Is there something else?").also { stage++ }
22 -> npcl(FacialExpression.NEUTRAL, "I used to be the cook for the old Duke of Lumbridge. Visiting dignitaries praised me for my fine banquets!"). also { stage++ }
23 -> npcl(FacialExpression.ANNOYED, "But then someone found a rule that said that only one family could hold that post.").also { stage++ }
24 -> npcl(FacialExpression.ANGRY, "Overnight I was fired and replaced by some fool who can't even bake a cake without help!").also { stage++ }
25 -> playerl(FacialExpression.NEUTRAL, "I'm sorry to hear that. It sounds as if you are a great cook!").also { stage++ }
26 -> npcl(FacialExpression.HAPPY, "Thanks, I am!").also { stage++ }
27 -> npcl(FacialExpression.LAUGH, "I also do this each year to show everyone how incapable that sorry excuse of a cook they replaced me with is.").also { stage++ }
28 -> npcl(FacialExpression.HAPPY, "So, did you want a cake?").also { stage++ }
29 -> options("Sure, I will take a cake.", "No, thanks.").also { stage++ }
30 -> when (buttonID) {
1 -> playerl(FacialExpression.HAPPY, "Sure, I will take a cake.").also { stage = 40 }
2 -> playerl(FacialExpression.NEUTRAL, "No, thanks.").also { stage = 10 }
}
40 -> npcl(FacialExpression.HAPPY, "Here is a the finest cake you will ever have! Merry Christmas, ${player!!.username.capitalize()}.").also { stage++ }
41 -> {
HolidayRandoms.terminateEventNpc(player!!)
addItemOrDrop(player!!, cakes.random())
end()
}
}
}
}

View file

@ -0,0 +1,32 @@
package core.game.worldevents.holiday.christmas.randoms
import core.api.*
import core.game.node.entity.npc.NPC
import core.game.worldevents.holiday.HolidayRandomEventNPC
import core.tools.RandomFunction
import core.tools.minutesToTicks
import org.rs09.consts.NPCs
class CookHolidayRandomNPC : HolidayRandomEventNPC(NPCs.COOK_4239) {
private val cookLines = listOf("@name, are you there?", "Would you like a fresh baked cake, @name?", "Happy Holidays, @name!")
private var hasTalkedWith = false
override fun init() {
ticksLeft = minutesToTicks(3)
sendChat(this, "Happy Holidays, ${player.username.capitalize()}!", 2)
super.init()
}
override fun tick() {
if (RandomFunction.roll(15) && !hasTalkedWith)
sendChat(this, cookLines.random().replace("@name",player.username.capitalize()))
super.tick()
}
override fun talkTo(npc: NPC) {
face(player)
hasTalkedWith = true
openDialogue(player, CookHolidayRandomDialogue(), npc)
}
}

View file

@ -0,0 +1,64 @@
package core.game.worldevents.holiday.christmas.randoms
import core.api.getPathableRandomLocalCoordinate
import core.api.*
import core.game.interaction.QueueStrength
import core.game.node.entity.impl.Projectile
import core.game.node.entity.npc.NPC
import core.game.world.map.path.Pathfinder
import core.game.world.update.flag.context.Graphics
import core.game.worldevents.holiday.HolidayRandomEventNPC
import core.tools.minutesToTicks
import org.rs09.consts.NPCs
import org.rs09.consts.Sounds
class JackFrostHolidayRandomNPC : HolidayRandomEventNPC(NPCs.JACK_FROST_8517) {
override fun init() {
ticksLeft = minutesToTicks(1)
spawnLocation = getPathableRandomLocalCoordinate(this, 3, player.location)
super.init()
}
override fun tick() {
if (getWorldTicks() % 5 == 0) {
if (this.location.withinDistance(player.location, 1) || this.location.getDistance(player.location).toInt() > 3) {
val path = Pathfinder.find(this, getPathableRandomLocalCoordinate(this, 3, player.location))
path.walk(this)
} else {
throwSnowball()
}
}
super.tick()
}
override fun talkTo(npc: NPC) {
sendMessage(player, "He does not seem interested in talking.")
}
override fun follow() {
}
private fun throwSnowball() {
queueScript(this, 0, QueueStrength.SOFT) { stage: Int ->
when (stage) {
0 -> {
face(this, player)
visualize(this, 7530, -1)
return@queueScript delayScript(this, 1)
}
1 -> {
Projectile.create(this, player, 861, 30, 10).send()
return@queueScript delayScript(this, this.location.getDistance(player.location).toInt())
}
2 -> {
player.graphics(Graphics(1282))
playGlobalAudio(player.location, Sounds.GUBLINCH_SNOWBALL_3295)
return@queueScript stopExecuting(this)
}
else -> return@queueScript stopExecuting(this)
}
}
}
}

View file

@ -0,0 +1,54 @@
package core.game.worldevents.holiday.christmas.randoms
import core.api.addItem
import core.api.addItemOrDrop
import core.api.getAttribute
import core.game.dialogue.DialogueFile
import core.game.dialogue.FacialExpression
import core.game.worldevents.holiday.HolidayRandoms
import core.game.worldevents.holiday.christmas.Giftmas
import core.tools.END_DIALOGUE
import core.tools.RandomFunction
import org.rs09.consts.Items
class SantaHolidayRandomDialogue : DialogueFile() {
override fun handle(componentID: Int, buttonID: Int) {
if (HolidayRandoms.getEventNpc(player!!) == null)
player!!.dialogueInterpreter.close()
when (stage) {
0 -> npcl(FacialExpression.JOLLY, "Ho Ho Ho!").also { stage++ }
1 -> npcl(FacialExpression.HAPPY, "Merry Christmas, ${player!!.username}! Would you like to know if you are on the nice or naughty list?").also { stage = 10 }
10 -> options("Yes, please.", "No, thanks."). also { stage = 11 }
11 -> when (buttonID) {
1 -> playerl(FacialExpression.HAPPY, "Yes, please.").also { stage = 20 }
2 -> {
playerl(FacialExpression.NEUTRAL, "No, thanks.")
stage = END_DIALOGUE
HolidayRandoms.terminateEventNpc(player!!)
}
}
20 -> if (getAttribute(HolidayRandoms.getEventNpc(player!!)!!, "playerisnice", false)) {
npcl(FacialExpression.HAPPY, "Let me check my list... ${player!!.username}.. You are on the nice list!").also { stage = 30 }
} else {
npcl(FacialExpression.SAD, "Let me check my list... ${player!!.username}.. You are on the naughty list!").also { stage = 40 }
}
30 -> npcl(FacialExpression.HAPPY, "Since you have been a good ${if (player!!.isMale) "boy" else "girl"} this year, you get a gift. Merry Christmas, ${player!!.username}!").also { stage = 31 }
31 -> {
val loot = Giftmas.MBOX_LOOT.roll().first()
addItem(player!!, loot.id, loot.amount)
HolidayRandoms.terminateEventNpc(player!!)
end()
}
40 -> npcl(FacialExpression.NEUTRAL, "If you work on being a good ${if (player!!.isMale) "boy" else "girl"} from now on you will make it on the nice list!").also { stage = 41 }
41 -> npcl(FacialExpression.NEUTRAL, "Since you are on the naughty list, you get coal.").also { stage = 42 }
42 -> {
addItemOrDrop(player!!, Items.COAL_454, RandomFunction.getRandom(20))
HolidayRandoms.terminateEventNpc(player!!)
end()
}
}
}
}

View file

@ -0,0 +1,31 @@
package core.game.worldevents.holiday.christmas.randoms
import core.api.*
import core.game.node.entity.npc.NPC
import core.game.worldevents.holiday.HolidayRandomEventNPC
import core.tools.RandomFunction
import core.tools.minutesToTicks
import org.rs09.consts.NPCs
class SantaHolidayRandomNPC() : HolidayRandomEventNPC(NPCs.SANTA_CLAUS_8540) {
override fun init() {
spawnLocation = getPathableRandomLocalCoordinate(this, 1, player.location)
super.init()
ticksLeft = minutesToTicks(2)
setAttribute(this, "playerisnice", !RandomFunction.roll(3))
sendChat(this, "Ho Ho Ho! Merry Christmas, ${player.username.capitalize()}!", 2)
}
override fun tick() {
if (RandomFunction.roll(10))
sendChat(this, "Ho Ho Ho! Merry Christmas, ${player.username.capitalize()}!")
super.tick()
}
override fun talkTo(npc: NPC) {
face(player)
openDialogue(player, SantaHolidayRandomDialogue(), npc)
}
}

View file

@ -0,0 +1,72 @@
package core.game.worldevents.holiday.christmas.randoms
import core.api.*
import core.game.node.entity.npc.NPC
import core.game.world.map.RegionManager
import core.game.world.map.path.Pathfinder
import core.game.worldevents.holiday.HolidayRandomEventNPC
import core.tools.RandomFunction
import core.tools.minutesToTicks
import org.rs09.consts.NPCs
import org.rs09.consts.Sounds
class SnowStormHolidayRandomNPC : HolidayRandomEventNPC(NPCs.SNOW_6740) {
private lateinit var snowTwoNPC: NPC
private lateinit var snowThreeNPC: NPC
private lateinit var snowFourNPC: NPC
private lateinit var snowFiveNPC: NPC
private lateinit var snowNPCs: List<NPC>
private val songs = listOf(189, 208, 209, 532, 547, 592)
private var snowFinalized = false
override fun init() {
snowTwoNPC = create(NPCs.SNOW_6740, getPathableRandomLocalCoordinate(player, 3, player.location))
snowThreeNPC = create(NPCs.SNOW_6740, getPathableRandomLocalCoordinate(player, 3, player.location))
snowFourNPC = create(NPCs.SNOW_6740, getPathableRandomLocalCoordinate(player, 3, player.location))
snowFiveNPC = create(NPCs.SNOW_6740, getPathableRandomLocalCoordinate(player, 3, player.location))
snowNPCs = listOf(this, snowTwoNPC, snowThreeNPC, snowFourNPC, snowFiveNPC)
ticksLeft = minutesToTicks(2)
super.init()
snowTwoNPC.init()
snowThreeNPC.init()
snowFourNPC.init()
snowFiveNPC.init()
val nearbyPlayers = RegionManager.getLocalPlayers(player.location, 8)
for (p in nearbyPlayers) {
p.musicPlayer.unlock(songs.random(), true)
}
}
override fun tick() {
if (getWorldTicks() % 8 == 0) {
moveSnow()
}
super.tick()
}
private fun moveSnow() {
for (snow in snowNPCs) {
val snowPath = Pathfinder.find(snow, getPathableRandomLocalCoordinate(player, 4, player.location))
snowPath.walk(snow)
if (RandomFunction.roll(4))
playGlobalAudio(snow.location, Sounds.ICY_WIND_2078)
}
}
override fun follow() {
}
override fun terminate() {
if (!snowFinalized) {
snowFinalized = true
for (snow in snowNPCs) {
poofClear(snow)
}
}
super.terminate()
}
override fun talkTo(npc: NPC) {
}
}

View file

@ -0,0 +1,21 @@
package core.game.worldevents.holiday.christmas.randoms
import core.api.getAttribute
import core.game.node.entity.Entity
import core.game.node.entity.combat.BattleState
import core.game.node.entity.npc.NPC
import core.game.node.entity.npc.NPCBehavior
import core.game.node.entity.player.Player
import core.game.worldevents.holiday.HolidayRandoms
import core.tools.RandomFunction
class SnowmanFightBehavior : NPCBehavior() {
override fun onDeathStarted(self: NPC, killer: Entity) {
val holidayRandomPlayer = getAttribute<Player?>(self, "holidayrandomplayer", null) ?: return
HolidayRandoms.terminateEventNpc(holidayRandomPlayer)
}
override fun beforeAttackFinalized(self: NPC, victim: Entity, state: BattleState) {
state.estimatedHit = RandomFunction.getRandom(1)
}
}

View file

@ -0,0 +1,52 @@
package core.game.worldevents.holiday.christmas.randoms
import core.api.*
import core.game.node.entity.npc.NPC
import core.game.worldevents.holiday.HolidayRandomEventNPC
import core.tools.minutesToTicks
import org.rs09.consts.NPCs
class SnowmanFightHolidayRandom : HolidayRandomEventNPC(NPCs.BARBARIAN_SNOWMAN_6742) {
private lateinit var otherSnowman: NPC
private val snowmen = listOf(NPCs.DRAGON_SNOWMAN_6743, NPCs.PIRATE_SNOWMAN_6745, NPCs.DWARF_SNOWMAN_6744)
private var snowmenFinalized = false
override fun init() {
otherSnowman = create(snowmen.random(), getPathableRandomLocalCoordinate(player, 3, player.location))
ticksLeft = minutesToTicks(3)
setAttribute(this, "holidayrandomplayer", player)
setAttribute(otherSnowman, "holidayrandomplayer", player)
setAttribute(otherSnowman, "holiday_random_extra_npc", true)
this.behavior = SnowmanFightBehavior()
otherSnowman.behavior = SnowmanFightBehavior()
super.init()
otherSnowman.init()
this.attack(otherSnowman)
otherSnowman.attack(this)
}
override fun tick() {
if (!this.inCombat() && getWorldTicks() % 20 == 0) {
this.teleport(otherSnowman.location)
this.attack(otherSnowman)
otherSnowman.attack(this)
}
super.tick()
}
override fun terminate() {
if (!snowmenFinalized) {
snowmenFinalized = true
poofClear(otherSnowman)
}
super.terminate()
}
override fun follow() {
}
override fun talkTo(npc: NPC) {
sendMessage(player, "They seem a little busy.")
}
}

View file

@ -0,0 +1,68 @@
package core.game.worldevents.holiday.christmas.randoms
import core.api.*
import core.game.dialogue.DialogueFile
import core.game.dialogue.FacialExpression
import core.game.interaction.QueueStrength
import core.game.node.entity.player.link.emote.Emotes
import core.game.worldevents.holiday.HolidayRandoms
import org.rs09.consts.Items
class SnowmanHolidayRandomDialogue : DialogueFile() {
override fun handle(componentID: Int, buttonID: Int) {
if (HolidayRandoms.getEventNpc(player!!) == null)
player!!.dialogueInterpreter.close()
when (stage) {
0 -> npcl(FacialExpression.CHILD_NEUTRAL, "Greetings, ${player!!.username.capitalize()}. I'm visiting from the Land of Snow, but I need some help."). also { stage++ }
1 -> options("What do you need?", "No, sorry.") .also { stage++ }
2 -> when(buttonID) {
1 -> playerl(FacialExpression.HALF_ASKING,"What do you need?").also { stage = 10 }
2 -> playerl(FacialExpression.NEUTRAL,"No, sorry.").also { stage = 30 }
}
10 -> npcl(FacialExpression.CHILD_NEUTRAL, "I visit Gielinor every year during this time when it is the coldest here, but it is still a little warm for us snowmen.").also { stage++ }
11 -> npcl(FacialExpression.CHILD_NEUTRAL, "I'm really enjoying my visit, but I have started to melt. Would you happen to have a snowball?").also { stage++ }
12 -> {
if (inInventory(player!!, Items.SNOWBALL_11951, 1)) {
playerl(FacialExpression.HAPPY, "Actually, I do! You can have it.").also { stage = 20 }
} else {
playerl(FacialExpression.NEUTRAL, "I don't have a snowball, sorry.").also { stage = 30 }
}
}
20 -> {
npcl(FacialExpression.CHILD_NEUTRAL, "Thank you, ${player!!.username.capitalize()}!").also { stage++ }
}
21 -> {
if (player!!.emoteManager.isUnlocked(Emotes.SNOWMAN_DANCE)) {
npcl(FacialExpression.CHILD_NEUTRAL, "Please take this lamp I found on my travels. Happy holidays, ${player!!.username.capitalize()}!").also { stage = 22 }
} else {
npcl(FacialExpression.CHILD_NEUTRAL, "Before I leave I will show you how to dance like us snowmen. Happy holidays, ${player!!.username.capitalize()}!").also { stage = 23 }
}
}
22 -> {
if (removeItem(player!!, Items.SNOWBALL_11951))
addItem(player!!, Items.LAMP_2528)
end()
HolidayRandoms.terminateEventNpc(player!!)
}
23 -> {
if (removeItem(player!!, Items.SNOWBALL_11951))
player!!.emoteManager.unlock(Emotes.SNOWMAN_DANCE)
queueScript(player!!, 2,QueueStrength.SOFT) {
sendDialogue(player!!, "You have unlocked the Snowman Dance emote!")
return@queueScript stopExecuting(player!!)
}
end()
HolidayRandoms.terminateEventNpc(player!!)
}
30 -> npcl(FacialExpression.CHILD_NEUTRAL, "I must be going before I melt. Happy Holidays, ${player!!.username.capitalize()}.").also { stage++ }
31 -> {
end()
HolidayRandoms.terminateEventNpc(player!!)
}
}
}
}

View file

@ -0,0 +1,32 @@
package core.game.worldevents.holiday.christmas.randoms
import core.api.*
import core.game.node.entity.npc.NPC
import core.game.worldevents.holiday.HolidayRandomEventNPC
import core.tools.RandomFunction
import core.tools.minutesToTicks
import org.rs09.consts.NPCs
class SnowmanHolidayRandomNPC : HolidayRandomEventNPC(NPCs.SNOWMAN_6746) {
private val snowmanLines = listOf("@name, are you there?", "Excuse me, @name?", "@name, could I please speak with you?")
private var hasTalkedWith = false
override fun init() {
super.init()
ticksLeft = minutesToTicks(2)
sendChat(this, "Happy holidays, ${player.username.capitalize()}!", 2)
}
override fun tick() {
if (RandomFunction.roll(15) && !hasTalkedWith)
sendChat(this, snowmanLines.random().replace("@name",player.username.capitalize()))
super.tick()
}
override fun talkTo(npc: NPC) {
face(player)
hasTalkedWith = true
openDialogue(player, SnowmanHolidayRandomDialogue(), npc)
}
}

View file

@ -1,15 +1,15 @@
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.node.entity.npc.NPC
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) {
class BlackCatHolidayRandomNPC() : HolidayRandomEventNPC(4607) {
override fun init() {
super.init()
queueScript(this, 8, QueueStrength.SOFT) {
@ -25,4 +25,7 @@ class BlackCatHolidayRandomNPC(override var loot: WeightBasedTable? = null) : Ho
return@queueScript stopExecuting(this)
}
}
override fun talkTo(npc: NPC) {
}
}

View file

@ -1,14 +1,14 @@
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.npc.NPC
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) {
class DeathHolidayRandomNPC() : HolidayRandomEventNPC(2862) {
override fun init() {
super.init()
playJingle(player, 337)
@ -36,4 +36,7 @@ class DeathHolidayRandomNPC(override var loot: WeightBasedTable? = null) : Holid
}
}
}
override fun talkTo(npc: NPC) {
}
}

View file

@ -1,12 +1,12 @@
package core.game.worldevents.holiday.halloween.randoms
import core.api.*
import core.api.utils.WeightBasedTable
import core.game.node.entity.npc.NPC
import core.game.worldevents.holiday.HolidayRandomEventNPC
import core.tools.RandomFunction
import org.rs09.consts.Sounds
class GhostHolidayRandomNPC(override var loot: WeightBasedTable? = null) : HolidayRandomEventNPC(2716) {
class GhostHolidayRandomNPC() : HolidayRandomEventNPC(2716) {
override fun init() {
super.init()
this.isAggressive = false
@ -21,4 +21,7 @@ class GhostHolidayRandomNPC(override var loot: WeightBasedTable? = null) : Holid
if (RandomFunction.roll(10))
playGlobalAudio(this.location, Sounds.BIGGHOST_LAUGH_1600)
}
override fun talkTo(npc: NPC) {
}
}

View file

@ -1,15 +1,15 @@
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.node.entity.npc.NPC
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) {
class SpiderHolidayRandomNPC() : HolidayRandomEventNPC(61) {
override fun init() {
super.init()
this.behavior = SpiderHolidayRandomBehavior()
@ -44,4 +44,7 @@ class SpiderHolidayRandomNPC(override var loot: WeightBasedTable? = null) : Holi
}
}
}
override fun talkTo(npc: NPC) {
}
}

View file

@ -1,9 +1,9 @@
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.node.entity.npc.NPC
import core.game.worldevents.holiday.HolidayRandomEventNPC
import core.game.worldevents.holiday.HolidayRandoms
import core.game.worldevents.holiday.ResetHolidayAppearance
@ -11,7 +11,7 @@ import core.tools.RandomFunction
import core.tools.colorize
import org.rs09.consts.Sounds
class VampireHolidayRandomNPC(override var loot: WeightBasedTable? = null) : HolidayRandomEventNPC(1023) {
class VampireHolidayRandomNPC() : HolidayRandomEventNPC(1023) {
override fun init() {
super.init()
playGlobalAudio(this.location, Sounds.REGULAR_VAMPIRE_APPEAR_1897)
@ -43,4 +43,7 @@ class VampireHolidayRandomNPC(override var loot: WeightBasedTable? = null) : Hol
}
}
}
override fun talkTo(npc: NPC) {
}
}

View file

@ -1,16 +1,16 @@
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.node.entity.npc.NPC
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) {
class WitchHolidayRandomNPC() : HolidayRandomEventNPC(611) {
override fun init() {
super.init()
when (RandomFunction.getRandom(4)) {
@ -146,4 +146,7 @@ class WitchHolidayRandomNPC(override var loot: WeightBasedTable? = null) : Holid
}
}
}
override fun talkTo(npc: NPC) {
}
}

View file

@ -1,9 +1,9 @@
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.node.entity.npc.NPC
import core.game.worldevents.holiday.ResetHolidayAppearance
import core.game.worldevents.holiday.HolidayRandomEventNPC
import core.game.worldevents.holiday.HolidayRandoms
@ -11,7 +11,7 @@ import core.tools.RandomFunction
import core.tools.colorize
import org.rs09.consts.Sounds
class ZombieHolidayRandomNPC(override var loot: WeightBasedTable? = null) : HolidayRandomEventNPC(2714) {
class ZombieHolidayRandomNPC() : HolidayRandomEventNPC(2714) {
override fun init() {
super.init()
this.isAggressive = false
@ -54,4 +54,7 @@ class ZombieHolidayRandomNPC(override var loot: WeightBasedTable? = null) : Holi
}
}
}
override fun talkTo(npc: NPC) {
}
}

View file

@ -101,6 +101,7 @@ new_player_announcement = true
holiday_event_randoms = true
#force holiday randoms (can only force one at a time)
force_halloween_randoms = false
force_christmas_randoms = false
# runecrafting formula revision (573 introduced probabilistic multiple runes, 581 extrapolated probabilistic runes past 99)
runecrafting_formula_revision = 581