Halloween Event 2021

This commit is contained in:
ceikry 2021-10-17 11:23:21 -05:00
parent 4c96da1fd3
commit bf497bae36
12 changed files with 489 additions and 30 deletions

View file

@ -24,5 +24,13 @@
<ObjectAction mode="add" id="20987" x="2821" y="2996" z="0" direction="s"/>
<ObjectAction mode="add" id="9472" x="3353" y="3951" z="0" direction="s"/>
<ObjectAction mode="add" id="21301" x="2662" y="3162" z="0" direction="e"/>
<!--HWEEN-->
<ObjectAction mode="add" id="39267" x="3101" y="3262" z="0" direction="s"/>
<ObjectAction mode="add" id="39267" x="3103" y="3266" z="0" direction="w"/>
<ObjectAction mode="add" id="39269" x="3095" y="3260" z="0" direction="n"/>
<ObjectAction mode="add" id="30320" x="3093" y="3256" z="0" direction="n"/>
<ObjectAction mode="add" id="30322" x="3092" y="3256" z="0" direction="n"/>
<ObjectAction mode="add" id="30319" x="3091" y="3256" z="0" direction="n"/>
</parsing>
</parsing>

View file

@ -139454,5 +139454,89 @@
"examine": "A chunk of rock.",
"name": "Rock",
"id": "1480"
},
{
"destroy": "true",
"turn90cw_anim": "1207",
"examine": "A staff with a spooky raven head attached.",
"walk_anim": "1205",
"low_alchemy": "80",
"turn90ccw_anim": "1208",
"attack_speed": "5",
"turn180_anim": "1206",
"defence_anim": "420",
"equipment_slot": "3",
"attack_anims": "419,419,419,419",
"stand_anim": "813",
"tradeable": "false",
"run_anim": "1210",
"archery_ticket_price": "0",
"id": "14654",
"stand_turn_anim": "1209",
"bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0",
"shop_price": "200",
"durability": null,
"high_alchemy": "120",
"weight": "2.2",
"weapon_interface": "1",
"render_anim": "28",
"attack_audios": "2555,0,0,0",
"name": "Staff of the raven"
},
{
"destroy": "true",
"turn90cw_anim": "1207",
"examine": "A staff with a spooky raven head attached.",
"walk_anim": "1205",
"low_alchemy": "80",
"turn90ccw_anim": "1208",
"attack_speed": "5",
"turn180_anim": "1206",
"defence_anim": "420",
"equipment_slot": "3",
"attack_anims": "419,419,419,419",
"stand_anim": "813",
"tradeable": "false",
"run_anim": "1210",
"archery_ticket_price": "0",
"id": "14655",
"stand_turn_anim": "1209",
"bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0",
"shop_price": "200",
"durability": null,
"high_alchemy": "120",
"weight": "2.2",
"weapon_interface": "1",
"render_anim": "28",
"attack_audios": "2555,0,0,0",
"name": "Staff of the raven"
},
{
"destroy": "true",
"turn90cw_anim": "1207",
"examine": "A staff with a spooky raven head attached.",
"walk_anim": "1205",
"low_alchemy": "80",
"turn90ccw_anim": "1208",
"attack_speed": "5",
"turn180_anim": "1206",
"defence_anim": "420",
"equipment_slot": "3",
"attack_anims": "419,419,419,419",
"stand_anim": "813",
"tradeable": "false",
"run_anim": "1210",
"archery_ticket_price": "0",
"id": "14656",
"stand_turn_anim": "1209",
"bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0",
"shop_price": "200",
"durability": null,
"high_alchemy": "120",
"weight": "2.2",
"weapon_interface": "1",
"render_anim": "28",
"attack_audios": "2555,0,0,0",
"name": "Staff of the raven"
}
]

View file

@ -2015,6 +2015,10 @@
"npc_id": "782",
"loc_data": "{3150,3406,0,0,0}"
},
{
"npc_id": "6390",
"loc_data": "{3094,3258,0,0,0}"
},
{
"npc_id": "783",
"loc_data": "{3221,3435,0,1,0}"

View file

@ -1,5 +1,6 @@
package core.game.interaction.item.toys;
import api.ContentAPI;
import core.game.component.Component;
import core.game.component.ComponentDefinition;
import core.game.component.ComponentPlugin;
@ -24,7 +25,7 @@ import java.util.Objects;
public class DiangoReclaimInterface extends ComponentPlugin {
private static final int COMPONENT_ID = 468;
public static final List<Item> ITEMS = new ArrayList<>(20);
public static final Item[] HOLIDAY_ITEMS = {YoyoPlugin.YOYO, ReindeerHatPlugin.ReindeerHat, BasketofEggsEvent.RUBBER_CHICKEN,ZombieHeadPlugin.ZOMBIE_HEAD, new Item(6857), new Item(6856), new Item(6858), new Item(6859), new Item(6860), new Item(6861), new Item(6862), new Item(6863), new Item(9920), new Item(9921),new Item(9922), new Item(9923), new Item(9924), new Item(9925), new Item(11019), new Item(11020), new Item(11021), new Item(11022), new Item(11789), new Item(11949), new Item(12634), new Item(14076), new Item(14077), new Item(14081),new Item(14595), new Item(14602), new Item(14603), new Item(14605)};
public static final Item[] HOLIDAY_ITEMS = {YoyoPlugin.YOYO, ReindeerHatPlugin.ReindeerHat, BasketofEggsEvent.RUBBER_CHICKEN,ZombieHeadPlugin.ZOMBIE_HEAD, new Item(6857), new Item(6856), new Item(6858), new Item(6859), new Item(6860), new Item(6861), new Item(6862), new Item(6863), new Item(9920), new Item(9921),new Item(9922), new Item(9923), new Item(9924), new Item(9925), new Item(11019), new Item(11020), new Item(11021), new Item(11022), new Item(11789), new Item(11949), new Item(12634), new Item(14076), new Item(14077), new Item(14081),new Item(14595), new Item(14602), new Item(14603), new Item(14605), new Item(14654)};
//initialize the plugin, add lists of items to the ITEMS list...
@Override
@ -43,7 +44,12 @@ public class DiangoReclaimInterface extends ComponentPlugin {
}
//filter out items the player already has in their bank, inventory, or equipped
Item[] reclaimables = ITEMS.stream().filter(Objects::nonNull).filter(item -> !player.getEquipment().containsItem(item) && !player.getInventory().containsItem(item) && !player.getBank().containsItem(item)).toArray(Item[]::new);
Item[] reclaimables = ITEMS.stream().filter(Objects::nonNull)
.filter(item -> !player.getEquipment().containsItem(item) && !player.getInventory().containsItem(item) && !player.getBank().containsItem(item)
&& (item.getId() != 14654
|| (!(ContentAPI.inInventory(player, 14655, 1) || ContentAPI.inEquipment(player, 14656, 1)) && player.getAttribute("sotr:purchased",false))
))
.toArray(Item[]::new);
//only send items if there are some to send
if(reclaimables.length > 0) {

View file

@ -26,7 +26,10 @@ import rs09.game.interaction.InteractionListener;
import rs09.game.interaction.InteractionListeners;
import rs09.game.world.repository.Repository;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.function.IntPredicate;
/**
* Handles the incoming interaction packets.
@ -34,6 +37,8 @@ import java.util.List;
*/
public final class InteractionPacket implements IncomingPacket {
static int[] hweenNPCs = new int[] {307, 375, 743, 744, 755, 2634, 2690, 2691, 2692, 530, 531, 556, 557, 558, 559, 583, 585, 1860, 3299, 3671, 922, 970};
@Override
public void decode(Player player, int opcode, IoBuffer buffer) {
if (player == null) {
@ -176,8 +181,13 @@ public final class InteractionPacket implements IncomingPacket {
return;
}
NPC shown = npc.getShownNPC(player);
final Option option = shown.getInteraction().get(optionIndex);
Option option = shown.getInteraction().get(optionIndex);
if (option == null) {
if (Arrays.stream(hweenNPCs).anyMatch(i -> i == shown.getId())) {
option = new Option("trick-or-treat", -1);
}
}
if(option == null) {
PacketRepository.send(ClearMinimapFlag.class, new PlayerContext(player));
Interaction.handleInvalidInteraction(player, npc, Option.NULL);
return;

View file

@ -4,6 +4,7 @@ import org.rs09.consts.Items
import rs09.game.content.ame.events.MysteriousOldManNPC
import rs09.game.content.ame.events.certer.CerterNPC
import rs09.game.content.ame.events.drilldemon.SeargentDamienNPC
import rs09.game.content.ame.events.evilchicken.EvilChickenNPC
import rs09.game.content.ame.events.sandwichlady.SandwichLadyRENPC
import rs09.game.content.global.WeightBasedTable
import rs09.game.content.global.WeightedItem
@ -28,6 +29,7 @@ enum class RandomEvents(val npc: RandomEventNPC, val loot: WeightBasedTable? = n
WeightedItem(Items.LOOP_HALF_OF_A_KEY_987,1,1,1.0)
)),
DRILL_DEMON(SeargentDamienNPC()),
EVIL_CHICKEN(EvilChickenNPC()),
SURPRISE_EXAM(MysteriousOldManNPC(),"sexam");
var type: String = ""

View file

@ -0,0 +1,36 @@
package rs09.game.content.ame.events.evilchicken
import core.game.node.entity.Entity
import core.game.node.entity.npc.NPC
import core.game.node.item.GroundItemManager
import core.game.node.item.Item
import core.tools.RandomFunction
import org.rs09.consts.Items
import rs09.game.content.ame.RandomEventNPC
import rs09.game.content.global.WeightBasedTable
val ids = 2463..2468
class EvilChickenNPC(override var loot: WeightBasedTable? = null) : RandomEventNPC(2463) {
override fun talkTo(npc: NPC) {}
override fun init() {
super.init()
val index = (player.properties.combatLevel / 20) - 1
val id = ids.toList()[index]
this.transform(id)
this.attack(player)
this.isRespawn = false
}
override fun finalizeDeath(killer: Entity?) {
super.finalizeDeath(killer)
GroundItemManager.create(Item(Items.FEATHER_314, RandomFunction.random(50,300)), this.dropLocation, player)
}
override fun tick() {
super.tick()
if(!player.viewport.currentPlane.npcs.contains(this)) this.clear()
}
}

View file

@ -1,11 +1,19 @@
package rs09.game.content.global.worldevents.holiday.halloween
import api.ContentAPI
import core.game.content.dialogue.DialoguePlugin
import core.game.content.dialogue.FacialExpression
import core.game.node.entity.combat.ImpactHandler
import core.game.node.entity.player.Player
import core.game.node.entity.player.link.emote.Emotes
import core.game.node.item.Item
import rs09.ServerStore
import rs09.ServerStore.getInt
import rs09.tools.END_DIALOGUE
/**
* Handles grim's dialogue for the 2021 halloween event.
*/
class GrimDialogue(player: Player? = null) : DialoguePlugin(player){
var firstSpeak = true
val candy = Item(14084)
@ -14,10 +22,11 @@ class GrimDialogue(player: Player? = null) : DialoguePlugin(player){
}
override fun open(vararg args: Any?): Boolean {
firstSpeak = !player.getAttribute("hween:grim_spoken",false)
firstSpeak = !player.getAttribute("hween2:grim_spoken",false)
if(firstSpeak){
npc("YOU! Yes.... you! Come here!")
player.musicPlayer.unlock(571)
stage = 0
} else {
npc("Hello, again, adventurer...")
@ -34,18 +43,20 @@ class GrimDialogue(player: Player? = null) : DialoguePlugin(player){
3 -> player(FacialExpression.THINKING,"Candy...? You want me to bring","you... candy?").also { stage++ }
4 -> npc("Yes, candy! Did I not speak clearly","enough?").also { stage++ }
5 -> player(FacialExpression.ASKING,"Well how do I even get candy?").also { stage++ }
6 -> npc("It seems my candy collection has been scattered","into everything in 2009Scape!").also { stage++ }
7 -> npc("I broke open a rock earlier when I was moving","my chair here, and I found one!").also { stage++ }
8 -> npc("I suspect some of the vile creatures of","2009Scape have gotten ahold of some as well.").also { stage++ }
9 -> npc("I need YOU to go collect this for me.").also { stage++ }
10 -> player(FacialExpression.THINKING,"And what will I get in exchange?").also { stage++ }
11 -> npc("Well I won't KILL YOU for starters.").also { stage++ }
12 -> player(FacialExpression.ANGRY_WITH_SMILE, "Is that it?!").also { stage++ }
13 -> npc("Well, I guess I could also give you this","odd currency. I suspect one of these mortal","shops allows you to buy holiday items with it.").also { stage++ }
14 -> player(FacialExpression.AMAZED, "YOU MEAN CREDITS?!").also { stage++ }
15 -> npc("Yes, I suppose I do.").also { stage++ }
16 -> npc("I will give you 2 credits for every candy","you bring me.").also { stage++ }
17 -> npc("NOW GET TO WORK!").also { player.setAttribute("/save:hween:grim_spoken",true); stage = 1000 }
6 -> npcl(FacialExpression.NEUTRAL,"It's Hallowe'en, you fool. Everyone's giving out candy.").also { stage++ }
7 -> npc("You'll need to go and ask them for it each day.").also { stage++ }
8 -> npc("You'll also need to be careful...","Something vile is on the prowl.").also { stage++ }
9 -> player(FacialExpression.THINKING,"And what will I get in exchange?").also { stage++ }
10 -> npc("Well I won't KILL YOU for starters.").also { stage++ }
11 -> player(FacialExpression.ANGRY_WITH_SMILE, "Is that it?!").also { stage++ }
12 -> npc("I've prepared a few... rewards, as well.").also { stage++ }
13 -> player(FacialExpression.AMAZED, "YOU MEAN CREDITS?!").also { stage++ }
14 -> npc("No, we're not doing that again.").also { stage++ }
15 -> player(FacialExpression.SAD,"Oh.").also { stage++ }
16 -> player(FacialExpression.NEUTRAL, "Ok, so what kind of rewards?").also { stage++ }
17 -> npcl(FacialExpression.NEUTRAL, "I've fashioned a special-made staff to give out for this year's event.").also { stage++ }
18 -> npcl(FacialExpression.NEUTRAL, "It is a decorative symbol of your engagement in this activity. Bring me candies, and it can be yours.").also { player.setAttribute("/save:hween2:grim_spoken",true); stage++ }
19 -> npc("NOW GET TO WORK!").also { player.setAttribute("/save:hween2:grim_spoken",true); stage = 1000 }
100 -> npc("I do hope you have... candy for me?").also { stage++ }
@ -54,15 +65,17 @@ class GrimDialogue(player: Player? = null) : DialoguePlugin(player){
} else {
player(FacialExpression.SAD, "No, I don't.").also { stage++ }
}
102 -> npc("THEN GET TO WORK!").also { player.impactHandler.manualHit(player,5,ImpactHandler.HitsplatType.DISEASE); stage++ }
103 -> player("YES SIR!").also { stage = 1000 }
102 -> npc("A shame, indeed. Your candy totals right now are ${getCandyTotals(player)}.").also { stage++ }
103 -> player(FacialExpression.FRIENDLY, "I'd like to see the reward shop, please.").also { stage++ }
104, 105 -> handleRewardShop(player, buttonId)
150 -> {
val candies = player.inventory.getAmount(candy)
player.inventory.remove(Item(candy.id,candies))
player.details.credits += candies * 2
npc("Thank you, adventurer, I have awarded you","with ${candies * 2} 'credits.'").also { stage = 1000 }
addToCandyTotal(player, candies)
npcl(FacialExpression.NEUTRAL, "Excellent, you now have ${getCandyTotals(player)} candies.")
stage = 103
}
@ -71,6 +84,143 @@ class GrimDialogue(player: Player? = null) : DialoguePlugin(player){
return true
}
fun handleRewardShop(player: Player, buttonId: Int){
val title = "You have ${getCandyTotals(player)} candies."
val hasUnlocked = player.getAttribute("sotr:purchased",false)
val hasRecolor1 = player.getAttribute("sotr:recolor1", false)
val hasRecolor2 = player.getAttribute("sotr:recolor2", false)
val hasEmote = player.emoteManager.isUnlocked(Emotes.TRICK)
if(!hasUnlocked && !hasEmote){
when(stage){
104 -> player.dialogueInterpreter.sendOptions(title, "Staff of the Raven (40c)", "Trick Emote (10c)").also { stage++ }
105 -> when(buttonId) {
1 -> if (canPurchase(player, 40)) buyStaff(player) else npc(
FacialExpression.NEUTRAL,
"You can't afford that."
)
2 -> if (canPurchase(player, 10)) buyEmote(player) else npc(
FacialExpression.NEUTRAL,
"You can't afford that"
)
}
}
}
else if(hasUnlocked && !hasEmote && !hasRecolor1 && !hasRecolor2){
when(stage){
104 -> player.dialogueInterpreter.sendOptions(title, "Staff Purple Recolor (10c)", "Staff Orange Recolor (10c)", "Trick Emote (10c)").also { stage++ }
105 -> when(buttonId){
1 -> if(canPurchase(player, 10)) buyRecolor1(player) else npc(FacialExpression.NEUTRAL, "You can't afford that.")
2 -> if(canPurchase(player, 10)) buyRecolor2(player) else npc(FacialExpression.NEUTRAL, "You can't afford that.")
3 -> if(canPurchase(player, 10)) buyEmote(player) else npc(FacialExpression.NEUTRAL, "You can't afford that.")
}
}
}
else if(hasUnlocked && !hasEmote && hasRecolor1 && !hasRecolor2){
when(stage){
104 -> player.dialogueInterpreter.sendOptions(title, "Staff Orange Recolor (10c)", "Trick Emote (10c)").also { stage++ }
105 -> when(buttonId){
1 -> if(canPurchase(player, 10)) buyRecolor2(player) else npc(FacialExpression.NEUTRAL, "You can't afford that.")
2 -> if(canPurchase(player, 10)) buyEmote(player) else npc(FacialExpression.NEUTRAL, "You can't afford that.")
}
}
}
else if(hasUnlocked && !hasEmote && !hasRecolor1 && hasRecolor2){
when(stage){
104 -> player.dialogueInterpreter.sendOptions(title, "Staff Purple Recolor (10c)", "Trick Emote (10c)").also { stage++ }
105 -> when(buttonId){
1 -> if(canPurchase(player, 10)) buyRecolor1(player) else npc(FacialExpression.NEUTRAL, "You can't afford that.")
2 -> if(canPurchase(player, 10)) buyEmote(player) else npc(FacialExpression.NEUTRAL, "You can't afford that.")
}
}
}
else if(!hasUnlocked && hasEmote){
when(stage){
104 -> player.dialogueInterpreter.sendOptions(title, "Staff of the Raven (40c)", "").also { stage++ }
105 -> when(buttonId){
1 -> if(canPurchase(player, 40)) buyStaff(player) else npc(FacialExpression.NEUTRAL, "You can't afford that.")
2 -> npc(FacialExpression.NEUTRAL, "Huhwuh").also { stage = 104 }
}
}
}
else if(hasUnlocked && hasEmote && !hasRecolor1 && !hasRecolor2){
when(stage){
104 -> player.dialogueInterpreter.sendOptions(title, "Staff Purple Recolor (10c)", "Staff Orange Recolor (10c)").also { stage++ }
105 -> when(buttonId){
1 -> if(canPurchase(player, 10)) buyRecolor1(player) else npc(FacialExpression.NEUTRAL, "You can't afford that.")
2 -> if(canPurchase(player, 10)) buyRecolor2(player) else npc(FacialExpression.NEUTRAL, "You can't afford that.")
}
}
}
else if(hasUnlocked && hasEmote && !hasRecolor1 && hasRecolor2){
when(stage){
104 -> player.dialogueInterpreter.sendOptions(title, "Staff Purple Recolor (10c)", "").also { stage++ }
105 -> when(buttonId){
1 -> if(canPurchase(player, 10)) buyRecolor1(player) else npc(FacialExpression.NEUTRAL, "You can't afford that.")
2 -> npc(FacialExpression.NEUTRAL, "Huhwuh").also { stage = 104 }
}
}
}
else if(hasUnlocked && hasEmote && hasRecolor1 && !hasRecolor2){
when(stage){
104 -> player.dialogueInterpreter.sendOptions(title, "Staff Orange Recolor (10c)", "").also { stage++ }
105 -> when(buttonId){
1 -> if(canPurchase(player, 10)) buyRecolor2(player) else npc(FacialExpression.NEUTRAL, "You can't afford that.")
2 -> npc(FacialExpression.NEUTRAL, "Huhwuh").also { stage = 104 }
}
}
}
else {
npcl(FacialExpression.NEUTRAL, "You've already bought everything.")
stage = END_DIALOGUE
}
}
fun buyStaff(player: Player){
player.setAttribute("/save:sotr:purchased", true)
removeCandies(player, 40)
ContentAPI.addItem(player, 14654, 1)
stage = 104
handleRewardShop(player, -1)
}
fun buyRecolor1(player: Player){
player.setAttribute("/save:sotr:recolor1", true)
removeCandies(player, 10)
stage = 104
handleRewardShop(player, -1)
}
fun buyRecolor2(player: Player){
player.setAttribute("/save:sotr:recolor2", true)
removeCandies(player, 10)
stage = 104
handleRewardShop(player, -1)
}
fun buyEmote(player: Player){
player.emoteManager.unlock(Emotes.TRICK)
removeCandies(player, 10)
stage = 104
handleRewardShop(player, -1)
}
fun canPurchase(player: Player, cost: Int) : Boolean {
return getCandyTotals(player) >= cost
}
fun removeCandies(player: Player, amount: Int){
addToCandyTotal(player, -amount)
}
fun getCandyTotals(player: Player): Int {
return ServerStore.getArchive("hween2021-candies").getInt(player.username.toLowerCase())
}
fun addToCandyTotal(player: Player, amount: Int){
ServerStore.getArchive("hween2021-candies").put(player.username.toLowerCase(), getCandyTotals(player) + amount)
}
override fun getIds(): IntArray {
return intArrayOf(6390)
}

View file

@ -9,22 +9,16 @@ import java.util.*
class SimpleHalloweenEvent : WorldEvent("hween"){
override fun checkActive(): Boolean {
return false
return true
}
override fun initialize() {
plugins = PluginSet(
CandyRewardPlugin(),
GrimDialogue()
)
val grim = NPC(6390, Location(3247,3198))
grim.isWalks = false
grim.walkRadius = 0
grim.isNeverWalks = true
grim.init()
super.initialize()
GameWorld.settings?.message_model = 800
GameWorld.settings?.message_string = "A mysterious figure has appeared in lumbridge cemetery! You should go investigate!"
GameWorld.settings?.message_string = "A mysterious figure has appeared in Draynor! You should go investigate!"
log("Initialized.")
}
}

View file

@ -0,0 +1,95 @@
package rs09.game.content.global.worldevents.holiday.halloween
import api.ContentAPI
import core.game.component.Component
import core.game.content.dialogue.FacialExpression
import core.game.node.entity.npc.NPC
import core.game.node.entity.player.Player
import core.game.system.task.Pulse
import core.game.world.map.Location
import core.game.world.update.flag.context.Animation
import core.game.world.update.flag.context.Graphics
import core.tools.RandomFunction
import org.rs09.consts.Components
import rs09.ServerStore
import rs09.ServerStore.getInt
import rs09.ServerStore.getString
import rs09.game.content.dialogue.DialogueFile
import rs09.game.interaction.InteractionListener
import rs09.game.world.GameWorld
import rs09.tools.END_DIALOGUE
class TrickOrTreatHandler : InteractionListener() {
override fun defineListeners() {
on(NPC, "trick-or-treat"){player, node ->
val hasDone5 = getDailyTrickOrTreats(player) == 5
val hasDoneMe = getTrickOrTreatedNPCs(player).contains(node.name.toLowerCase())
if(hasDone5){
ContentAPI.sendNPCDialogue(player, node.id, "My informants tell me you've already collected candy from 5 people today.", FacialExpression.FRIENDLY)
return@on true
}
if(hasDoneMe){
ContentAPI.sendNPCDialogue(player, node.id, "You've already asked me today! Don't get greedy, now.", FacialExpression.ANNOYED)
return@on true
}
player.dialogueInterpreter.open(object : DialogueFile(){
override fun handle(componentID: Int, buttonID: Int) {
when(stage){
0 -> playerl(FacialExpression.FRIENDLY, "Trick or treat!").also { if(RandomFunction.roll(20)) stage = 10 else stage++ }
1 -> npcl(FacialExpression.FRIENDLY, "Very well, then, here you are my friend.").also { stage++ }
2 -> {
player.dialogueInterpreter.sendItemMessage(14084, "They hand you a nicely-wrapped candy.")
ContentAPI.addItemOrDrop(player, 14084, 1)
registerNpc(player, npc!!)
incrementDailyToT(player)
stage = END_DIALOGUE
}
10 -> npcl(FacialExpression.EVIL_LAUGH, "I CHOOSE TRICK!").also { player.lock(); GameWorld.submit(object : Pulse() {
var counter = 0
override fun pulse(): Boolean {
//gfx 1898
when(counter++){
0 -> npc!!.visualize(Animation(1979), Graphics(1898)).also { npc!!.faceLocation(player.location) }
2 -> player.dialogueInterpreter.close()
5 -> player.interfaceManager.open(Component(Components.FADE_TO_BLACK_120))
8 -> player.properties.teleportLocation = Location.create(3106, 3382, 0)
12 -> {
player.interfaceManager.close()
player.interfaceManager.open(Component(Components.FADE_FROM_BLACK_170))
registerNpc(player, npc!!)
}
15 -> player.interfaceManager.close().also { player.unlock() }
16 -> return true
}
return false
}
}) }
}
}
}, node.asNpc())
return@on true
}
}
fun incrementDailyToT(player: Player){
ServerStore.getArchive("daily-tot-total")[player.username.toLowerCase()] = getDailyTrickOrTreats(player) + 1
}
fun getDailyTrickOrTreats(player: Player) : Int {
return ServerStore.getArchive("daily-tot-total").getInt(player.username.toLowerCase())
}
fun getTrickOrTreatedNPCs(player: Player): String {
return ServerStore.getArchive("daily-tot-npcs").getString(player.username.toLowerCase())
}
fun registerNpc(player: Player, npc: NPC){
var soFar = getTrickOrTreatedNPCs(player)
soFar += ":" + npc.name.toLowerCase() + ":"
ServerStore.getArchive("daily-tot-npcs")[player.username.toLowerCase()] = soFar
}
}

View file

@ -0,0 +1,70 @@
package rs09.game.interaction.item
import api.ContentAPI
import core.game.node.entity.player.Player
import core.game.node.item.Item
import core.game.world.update.flag.context.Graphics
import rs09.game.content.dialogue.DialogueFile
import rs09.game.interaction.InteractionListener
import rs09.tools.END_DIALOGUE
/**
* Handles the Staff of the Raven's (2021 Hween Reward) Recolor Transformation
*/
class StaffOfTheRaven : InteractionListener() {
val ids = intArrayOf(14654, 14655, 14656)
override fun defineListeners() {
on(ids, ITEM, "recolor", "operate"){player, node ->
val hasUnlocked = player.getAttribute("sotr:purchased",false)
val hasRecolorA = player.getAttribute("sotr:recolor1", false)
val hasRecolorB = player.getAttribute("sotr:recolor2", false)
val isBase = node.id == 14654
val isOperate = ContentAPI.getUsedOption(player) == "operate"
if(!hasUnlocked){
//Remove the item if the player has not purchased it. Just in case.
switchStaff(player, null, isOperate, node.asItem())
return@on true
}
if(!isBase){
switchStaff(player, 14654, isOperate, node.asItem())
return@on true
}
player.dialogueInterpreter.open(object : DialogueFile(){
override fun handle(componentID: Int, buttonID: Int) {
if(!hasRecolorA && !hasRecolorB){
dialogue("You do not have any recolors unlocked.")
stage = END_DIALOGUE
} else if(hasRecolorA && !hasRecolorB){
switchStaff(player, 14655, isOperate, node.asItem())
} else if(hasRecolorB && !hasRecolorA){
switchStaff(player, 14656, isOperate, node.asItem())
} else {
when (stage) {
0 -> options("Purple", "Orange").also { stage++ }
1 -> when (buttonID) {
1 -> switchStaff(player, 14655, isOperate, node.asItem())
2 -> switchStaff(player, 14656, isOperate, node.asItem())
else -> { }
}.also { end() }
}
}
}
})
return@on true
}
}
fun switchStaff(player: Player, to: Int?, equipped: Boolean, original: Item){
player.graphics(Graphics(1119))
val item: Item? = if(to != null) Item(to) else to
if(equipped){
player.equipment.replace(item, original.slot)
} else {
player.inventory.replace(item, original.slot)
}
}
}

View file

@ -424,7 +424,7 @@ class MiscCommandSet : CommandSet(Command.Privilege.ADMIN){
}
define("testlady",Command.Privilege.ADMIN){player,_ ->
player.antiMacroHandler.event = RandomEvents.SURPRISE_EXAM.npc.create(player,null,"sexam")
player.antiMacroHandler.event = RandomEvents.EVIL_CHICKEN.npc.create(player,null,"sexam")
player.antiMacroHandler.event!!.init()
}