Drill demon, sandwich lady and certer random events.

This commit is contained in:
Ceikry
2021-03-17 22:41:59 -05:00
parent c88d45367d
commit 6deecb0b1c
26 changed files with 695 additions and 151 deletions
+4
View File
@@ -10546,6 +10546,10 @@
{
"npc_id": "4965",
"loc_data": "{2824,3685,0,0,1}"
},
{
"npc_id": "2790",
"loc_data": "{3163,4822,0,0,6}"
}
]
@@ -53,7 +53,6 @@ public abstract class AntiMacroDialogue extends DialoguePlugin {
asAme().getProperties().getCombatPulse().stop();
}
setEvent(player.getAntiMacroHandler().getEvent());
return true;
}
@@ -1,17 +1,15 @@
package core.game.content.ame;
import core.cache.misc.buffer.ByteBufferUtils;
import rs09.game.system.SystemLogger;
import core.game.world.map.zone.impl.WildernessZone;
import core.game.node.entity.skill.Skills;
import core.game.node.entity.npc.NPC;
import core.game.node.entity.player.Player;
import rs09.game.world.GameWorld;
import core.game.node.entity.skill.Skills;
import core.game.world.map.zone.ZoneRestriction;
import core.game.world.map.zone.impl.WildernessZone;
import core.tools.RandomFunction;
import rs09.game.content.ame.RandomEventNPC;
import rs09.game.system.SystemLogger;
import rs09.game.world.GameWorld;
import java.nio.ByteBuffer;
import java.util.HashMap;
import java.util.Map;
@@ -56,7 +54,7 @@ public final class AntiMacroHandler {
/**
* The current event.
*/
private AntiMacroEvent event;
private RandomEventNPC event;
public ExperienceMonitor[] monitors = new ExperienceMonitor[Skills.SKILL_NAME.length];
@@ -68,14 +66,6 @@ public final class AntiMacroHandler {
this.player = player;
}
/**
* Checks if saving is required.
* @return {@code True} if so.
*/
public boolean isSaveRequired() {
return hasEvent() && event.isSaveRequired();
}
/**
* Gets called every game pulse.
*/
@@ -116,9 +106,6 @@ public final class AntiMacroHandler {
} else {
nextPulse = GameWorld.getTicks() + DELAY;
}
if (event != null) {
event.start(player, true);
}
if(!player.isArtificial() && !isDisabled) {
SystemLogger.logInfo("Anti-Macro: Initialized anti-macro handler for " + player.getUsername());
}
@@ -147,12 +134,12 @@ public final class AntiMacroHandler {
return false;
}
AntiMacroNPC n = (AntiMacroNPC) npc;
if (n.getEvent() != event) {
/*if (n.getEvent() != event) {
if (message) {
player.getPacketDispatch().sendMessage("They don't seem interested in talking to you.");
}
return false;
}
}*/
return true;
}
@@ -183,7 +170,7 @@ public final class AntiMacroHandler {
return false;
}
//resetTrigger();
this.event = event;
//this.event = event;
return true;
}
@@ -194,7 +181,7 @@ public final class AntiMacroHandler {
* @return {@code True} if the event has been fired.
*/
public boolean fireEvent(int skillId, Object... args) {
nextPulse = DELAY + GameWorld.getTicks();
/*nextPulse = DELAY + GameWorld.getTicks();
if (hasEvent() || EVENTS.isEmpty() || player.getZoneMonitor().isRestricted(ZoneRestriction.RANDOM_EVENTS) || player.isArtificial()) {
return false;
}
@@ -207,7 +194,7 @@ public final class AntiMacroHandler {
return true;
}
event = null;
}
}*/
return false;
}
@@ -236,7 +223,7 @@ public final class AntiMacroHandler {
* @return {@code True} if so.
*/
public boolean hasEvent() {
return event != null && !event.isTerminated();
return event != null;
}
/**
@@ -251,7 +238,7 @@ public final class AntiMacroHandler {
* Gets the event.
* @return The event.
*/
public AntiMacroEvent getEvent() {
public RandomEventNPC getEvent() {
return event;
}
@@ -259,7 +246,7 @@ public final class AntiMacroHandler {
* Sets the event.
* @param event The event to set.
*/
public void setEvent(AntiMacroEvent event) {
public void setEvent(RandomEventNPC event) {
this.event = event;
}
}
@@ -1,14 +1,12 @@
package core.game.content.ame.events.genie;
import java.nio.ByteBuffer;
import core.game.content.ame.AntiMacroDialogue;
import core.game.content.ame.AntiMacroEvent;
import core.plugin.Initializable;
import core.game.content.dialogue.DialoguePlugin;
import core.game.node.entity.player.Player;
import core.game.node.item.Item;
import core.game.world.map.Location;
import core.plugin.Initializable;
import rs09.plugin.PluginManager;
/**
@@ -98,7 +96,6 @@ public final class GenieRandomEvent extends AntiMacroEvent {
@Override
public boolean open(Object... args) {
if (super.open(args)) {
npc("Ah, so you are there " + player.getAntiMacroHandler().getEvent().getGenderPrefix().toLowerCase() + ". I'm so glad you", "summoned me. Please take this lamp and make your", "wish!");
}
return true;
}
@@ -52,10 +52,6 @@ import core.game.world.map.*;
import core.game.world.map.build.DynamicRegion;
import core.game.world.map.path.Pathfinder;
import core.game.world.map.zone.ZoneType;
import rs09.game.world.update.MapChunkRenderer;
import rs09.game.world.update.NPCRenderer;
import rs09.game.world.update.PlayerRenderer;
import rs09.game.world.update.UpdateSequence;
import core.game.world.update.flag.PlayerFlags;
import core.game.world.update.flag.context.Animation;
import core.game.world.update.flag.context.Graphics;
@@ -73,6 +69,8 @@ import core.net.packet.out.UpdateSceneGraph;
import core.plugin.Plugin;
import core.tools.RandomFunction;
import core.tools.StringUtils;
import kotlin.Unit;
import kotlin.jvm.functions.Function1;
import rs09.ServerConstants;
import rs09.game.VarpManager;
import rs09.game.ge.PlayerGrandExchange;
@@ -83,6 +81,10 @@ import rs09.game.node.entity.state.newsys.State;
import rs09.game.node.entity.state.newsys.StateRepository;
import rs09.game.world.GameWorld;
import rs09.game.world.repository.Repository;
import rs09.game.world.update.MapChunkRenderer;
import rs09.game.world.update.NPCRenderer;
import rs09.game.world.update.PlayerRenderer;
import rs09.game.world.update.UpdateSequence;
import rs09.tools.TickUtilsKt;
import java.util.*;
@@ -121,6 +123,8 @@ public class Player extends Entity {
public HashMap<String,State> states = new HashMap<>();
public HashMap<String,Function1<Player, Unit>> logoutListeners = new HashMap<>();
/**
* The inventory.
*/
@@ -404,6 +408,9 @@ public class Player extends Entity {
}
});
}
if(!logoutListeners.isEmpty()){
logoutListeners.forEach((key,method) -> method.invoke(this));
}
if (familiarManager.hasFamiliar()) {
familiarManager.getFamiliar().clear();
}
@@ -1363,4 +1370,12 @@ public class Player extends Entity {
state.getPulse().stop();
states.remove(key);
}
public void addLogoutListener(String key, Function1<Player,Unit> listener){
logoutListeners.put(key,listener);
}
public void removeLogoutListener(String key){
logoutListeners.remove(key);
}
}
@@ -64,6 +64,8 @@ public final class DynamicRegion extends Region {
*/
private DynamicRegion parentRegion;
public ArrayList<NPC> NPCs = new ArrayList<>(10);
/**
* Constructs a new {@code DynamicRegion} {@code Object}.
* @param regionId The region id of the region to copy.
@@ -467,4 +469,11 @@ public final class DynamicRegion extends Region {
public DynamicRegion getParent() {
return parentRegion;
}
public void clear(){
for(NPC n : NPCs){
n.clear();
}
NPCs.clear();
}
}
@@ -0,0 +1,103 @@
package rs09.game.content.ame
import core.game.interaction.MovementPulse
import core.game.node.entity.npc.NPC
import core.game.node.entity.player.Player
import core.game.node.item.Item
import core.game.system.task.Pulse
import core.game.world.map.Location
import core.game.world.map.RegionManager
import core.game.world.map.path.Pathfinder
import core.game.world.update.flag.context.Graphics
import rs09.game.content.global.WeightBasedTable
import rs09.game.world.GameWorld.Pulser
import rs09.tools.secondsToTicks
import kotlin.random.Random
import kotlin.reflect.full.createInstance
abstract class RandomEventNPC(id: Int) : NPC(id) {
lateinit var player: Player
abstract var loot: WeightBasedTable?
var spawnLocation: Location? = null
val SMOKE_GRAPHICS = Graphics(86)
var initialized = false
var ticksLeft = secondsToTicks(600)
open fun create(player: Player, loot: WeightBasedTable? = null): RandomEventNPC{
val event = this::class.createInstance()
event.loot = loot
event.player = player
event.spawnLocation = RegionManager.getSpawnLocation(player,this)
return event
}
open fun terminate(){
player.antiMacroHandler.event = null
if(initialized){
Pulser.submit(object : Pulse(){
var counter = 0
override fun pulse(): Boolean {
when(counter++){
2 -> {
isInvisible = true; Graphics.send(SMOKE_GRAPHICS, location)
}
3 -> clear().also { return true }
}
return false
}
})
}
}
open fun follow(){
pulseManager.run(object : MovementPulse(this,player, Pathfinder.DUMB){
override fun pulse(): Boolean {
face(player)
7
return false
}
})
}
override fun tick() {
super.tick()
ticksLeft--
if(!pulseManager.hasPulseRunning()) follow()
if(!player.isActive || !player.location.withinDistance(location,10)){
terminate()
}
if(ticksLeft <= 0){
onTimeUp()
}
}
override fun init() {
spawnLocation ?: terminate()
location = spawnLocation
initialized = true
super.init()
}
open fun onTimeUp(){
noteAndTeleport()
terminate()
}
fun noteAndTeleport(){
for(item in player.inventory.toArray()){
if(item == null) continue
if(item.noteChange != item.id){
player.inventory.remove(item)
player.inventory.add(Item(item.noteChange,item.amount))
}
}
if(Random.nextBoolean()){
player.properties.teleportLocation = Location.create(3197, 3223, 0)
} else {
player.properties.teleportLocation = Location.create(3212, 9620, 0)
}
player.graphics(SMOKE_GRAPHICS)
}
abstract fun talkTo(npc: NPC)
}
@@ -0,0 +1,35 @@
package rs09.game.content.ame
import org.rs09.consts.Items
import rs09.game.content.ame.events.certer.CerterNPC
import rs09.game.content.ame.events.drilldemon.SeargentDamienNPC
import rs09.game.content.ame.events.sandwichlady.SandwichLadyRENPC
import rs09.game.content.global.WeightBasedTable
import rs09.game.content.global.WeightedItem
enum class RandomEvents(val npc: RandomEventNPC, val loot: WeightBasedTable? = null) {
SANDWICH_LADY(SandwichLadyRENPC()),
CERTER(CerterNPC(),WeightBasedTable.create(
WeightedItem(Items.COINS_995,1,100,2.0),
WeightedItem(Items.SPINACH_ROLL_1969,1,1,2.0),
WeightedItem(Items.KEBAB_1971,1,1,2.0),
WeightedItem(Items.UNCUT_SAPPHIRE_1623,1,1,0.5),
WeightedItem(Items.SAPPHIRE_1607,1,1,0.5),
WeightedItem(Items.UNCUT_EMERALD_1621,1,1,0.25),
WeightedItem(Items.EMERALD_1605,1,1,0.25),
WeightedItem(Items.UNCUT_RUBY_1619,1,1,0.15),
WeightedItem(Items.RUBY_1603,1,1,0.15),
WeightedItem(Items.DIAMOND_1601,1,1,0.1),
WeightedItem(Items.UNCUT_DIAMOND_1617,1,1,0.1),
WeightedItem(Items.COSMIC_TALISMAN_1454,1,1,0.15),
WeightedItem(Items.NATURE_TALISMAN_1462,1,1,0.15),
WeightedItem(Items.TOOTH_HALF_OF_A_KEY_985,1,1,1.0),
WeightedItem(Items.LOOP_HALF_OF_A_KEY_987,1,1,1.0)
)),
DRILL_DEMON(SeargentDamienNPC());
companion object {
@JvmField
val randomIDs = values().map { it.npc.id }.toList()
}
}
@@ -1,22 +0,0 @@
package rs09.game.content.ame.events
import core.game.component.Component
import org.rs09.consts.NPCs
import rs09.game.interaction.InteractionListener
class SandwichLadyHandler : InteractionListener(){
val SANDWICH_LADY = NPCs.SANDWICH_LADY_3117
override fun defineListeners() {
on(SANDWICH_LADY,NPC,"talk-to"){player, node ->
if(player.antiMacroHandler?.hasEvent()!! && player.antiMacroHandler.event.name == "Sandwich Lady") {
player.interfaceManager?.open(Component(297))
node.asNpc().clear()
} else {
player.sendMessage("She isn't interested in you.")
}
return@on true
}
}
}
@@ -1,83 +0,0 @@
package rs09.game.content.ame.events
import core.game.content.ame.AntiMacroEvent
import core.game.content.ame.AntiMacroHandler
import core.game.interaction.DestinationFlag
import core.game.interaction.MovementPulse
import core.game.node.entity.npc.AbstractNPC
import core.game.node.entity.player.Player
import core.game.world.map.Location
import core.plugin.Initializable
import core.tools.RandomFunction
@Initializable
class SandwichLadyEvent : AntiMacroEvent("Sandwich Lady",false,false, 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23){
override fun start(player: Player?, login: Boolean, vararg args: Any?): Boolean {
super.init(player)
val location = Location.getRandomLocation(player?.location,6,true)
val npc = SandwichLadyNPC(location,player)
npc.init()
if(location == player?.location)
npc.moveStep()
return true
}
override fun configure() {
}
override fun create(player: Player?): AntiMacroEvent {
val event = SandwichLadyEvent()
event.player = player
return event
}
override fun getSpawnLocation(): Location {
return Location(0,0,0)
}
override fun newInstance(player: Player?): AntiMacroEvent {
AntiMacroHandler.register(this)
return super.newInstance(player)
}
class SandwichLadyNPC(loc: Location, var player: Player?) : AbstractNPC(3117,loc){
val QUOTES = arrayListOf<String>("Hello ${player?.username}, are you there?","Sandwiches, ${player?.username}!","Are you ignoring me?","I have sandwiches for you.","${player?.username}? Can you hear me?")
override fun init() {
super.init()
}
override fun handleTickActions() {
if(player == null || player?.isActive == false || player?.location?.withinDistance(this.location) == false){
onRegionInactivity()
}
if(RandomFunction.random(20) == 3){
sendChat(QUOTES.random())
}
class followPulse(val p: Player?) : MovementPulse(this,p,DestinationFlag.ENTITY){
override fun pulse(): Boolean {
face(p)
return true
}
}
if(!pulseManager.hasPulseRunning()) {
pulseManager.run(followPulse(player))
}
super.handleTickActions()
}
override fun getIds(): IntArray {
return intArrayOf(3117)
}
override fun onRegionInactivity() {
super.onRegionInactivity()
clear()
}
override fun construct(id: Int, location: Location?, vararg objects: Any?): AbstractNPC {
return SandwichLadyNPC(location!!,player)
}
}
}
@@ -0,0 +1,31 @@
package rs09.game.content.ame.events.certer
import core.game.component.Component
import rs09.game.content.dialogue.DialogueFile
import rs09.tools.END_DIALOGUE
class CerterDialogue(val initial: Boolean) : DialogueFile() {
val CERTER_INTERFACE = 184
override fun handle(componentID: Int, buttonID: Int) {
if(initial){
when(stage){
0 -> npc("Ah, hello, ${player!!.username.capitalize()}. Could you","please help me identify this?").also { stage++ }
1 -> {
end()
player!!.interfaceManager.open(Component(CERTER_INTERFACE))
}
}
} else {
val isCorrect = player!!.getAttribute("certer:correct",false)
when(stage){
0 -> if(!isCorrect) npc("Sorry, I don't think so.").also { stage = END_DIALOGUE; player!!.antiMacroHandler.event.terminate() } else npc("Oh yes! That's right.").also { stage++ }
1 -> {
npc("Please, take this as a thanks.")
player!!.antiMacroHandler.event.loot!!.roll(player!!).forEach { player!!.inventory.add(it) }
player!!.antiMacroHandler.event.terminate()
stage = END_DIALOGUE
}
}
}
}
}
@@ -0,0 +1,65 @@
package rs09.game.content.ame.events.certer
import core.game.node.entity.player.Player
import org.rs09.consts.Items
import rs09.game.interaction.InterfaceListener
class CerterEventInterface : InterfaceListener() {
val CERTER_INTERFACE = 184
val OPTION_A_CHILD = 1
val OPTION_B_CHILD = 2
val OPTION_C_CHILD = 3
val ITEM_CHILD = 7
val items = mapOf(
Items.BRONZE_SCIMITAR_1321 to "a sword",
Items.BRONZE_SWORD_1277 to "a sword",
Items.BRONZE_MED_HELM_1139 to "a helmet",
Items.BRONZE_FULL_HELM_1155 to "a helmet",
Items.WOODEN_SHIELD_1171 to "a shield",
Items.BRONZE_KITESHIELD_1189 to "a shield",
)
val falseOptions = arrayOf("a ring","a dragon","a cat","a chestplate","a pair of boots","a fish","a gun","a staff","a cannon","a dwarf","a bow","an arrow","a chinchompa","a chicken","a feather","a ninja","a bot")
override fun defineListeners() {
on(CERTER_INTERFACE){player, _, _, buttonID, _, _ ->
val answer = buttonID - 7
val correctAnswer = player.getAttribute("certer:correctIndex",0)
player.setAttribute("certer:correct",correctAnswer == answer)
player.interfaceManager.close()
player.dialogueInterpreter.open(CerterDialogue(false),player.antiMacroHandler.event.asNpc())
return@on true
}
onOpen(CERTER_INTERFACE){player, _ ->
generateOptions(player)
return@onOpen true
}
}
fun generateOptions(player: Player) {
val correct = items.keys.random()
val indexes = arrayListOf(1,2,3)
val correctIndex = indexes.random()
indexes.remove(correctIndex)
player.setAttribute("certer:correctIndex",correctIndex)
player.packetDispatch.sendString(items[correct],CERTER_INTERFACE,optionFromIndex(correctIndex))
val tempOptions = falseOptions
val false1 = tempOptions.random()
var false2 = tempOptions.random()
while(false1 == false2) false2 = tempOptions.random()
player.packetDispatch.sendString(false1,CERTER_INTERFACE,optionFromIndex(indexes[0]))
player.packetDispatch.sendString(false2,CERTER_INTERFACE,optionFromIndex(indexes[1]))
player.packetDispatch.sendItemOnInterface(correct,1,CERTER_INTERFACE,ITEM_CHILD)
}
fun optionFromIndex(index: Int): Int{
return when(index){
1 -> OPTION_A_CHILD
2 -> OPTION_B_CHILD
3 -> OPTION_C_CHILD
else -> OPTION_A_CHILD
}
}
}
@@ -0,0 +1,23 @@
package rs09.game.content.ame.events.certer
import core.game.node.entity.npc.NPC
import core.tools.RandomFunction
import org.rs09.consts.NPCs
import rs09.game.content.ame.RandomEventNPC
import rs09.game.content.global.WeightBasedTable
class CerterNPC(override var loot: WeightBasedTable? = null) : RandomEventNPC(NPCs.GILES_2538) {
override fun tick() {
super.tick()
if(RandomFunction.random(1,10) == 5) sendChat(player.username.capitalize() + "! I need your assistance.")
}
override fun talkTo(npc: NPC) {
player.dialogueInterpreter.open(CerterDialogue(true),npc)
}
override fun init() {
super.init()
sendChat(player.username.capitalize() + "! I need your assistance.")
}
}
@@ -0,0 +1,49 @@
package rs09.game.content.ame.events.drilldemon
import core.game.node.entity.npc.NPC
import core.game.system.task.Pulse
import org.rs09.consts.NPCs
import rs09.game.interaction.InteractionListener
class DrillDemonListeners : InteractionListener() {
val MATS = intArrayOf(10076,10077,10078,10079)
override fun defineListeners() {
on(MATS,OBJECT,"use"){player, node ->
val correctTask = player.getAttribute(DrillDemonUtils.DD_KEY_TASK,-1)
if(correctTask == -1){
player.sendMessage("You can't do that right now.")
return@on true
}
val task = DrillDemonUtils.getMatTask(node.id,player)
val npc = NPC(NPCs.SERGEANT_DAMIEN_2790)
player.lock()
val anim = DrillDemonUtils.animationForTask(task)
player.walkingQueue.reset()
player.walkingQueue.addPath(node.location.x,4820)
player.pulseManager.run(object : Pulse(){
var counter = 0
override fun pulse(): Boolean {
when(counter++){
2 -> player.faceLocation(player.location.transform(0,-1,0))
3 -> player.animator.animate(DrillDemonUtils.animationForTask(task)).also { delay = anim.duration / 2 }
6 -> {
if(task == correctTask){
player.incrementAttribute(DrillDemonUtils.DD_CORRECT_COUNTER)
player.dialogueInterpreter.open(SeargentDamienDialogue(true),npc)
} else {
player.dialogueInterpreter.open(SeargentDamienDialogue(false),npc)
}
return true
}
}
return false
}
})
return@on true
}
}
}
@@ -0,0 +1,112 @@
package rs09.game.content.ame.events.drilldemon
import core.game.content.dialogue.FacialExpression
import core.game.node.entity.player.Player
import core.game.node.item.GroundItemManager
import core.game.node.item.Item
import core.game.world.map.Location
import core.game.world.update.flag.context.Animation
import org.rs09.consts.Items
import org.rs09.consts.NPCs
object DrillDemonUtils {
val DD_KEY_NPC = "drilldemon:npc"
val DD_KEY_TASK = "drilldemon:task"
val DD_KEY_RETURN_LOC = "drilldemon:original-loc"
val DD_SIGN_VARP = 531
val DD_SIGN_JOG = 0
val DD_SIGN_SITUP = 1
val DD_SIGN_PUSHUP = 2
val DD_SIGN_JUMP = 3
val DD_CORRECT_OFFSET = "drilldemon:offset"
val DD_CORRECT_COUNTER = "drilldemon:numcorrect"
fun teleport(player: Player){
player.setAttribute(DD_KEY_RETURN_LOC,player.location)
player.properties.teleportLocation = Location.create(3163, 4819, 0)
player.addLogoutListener("drilldemon") { p ->
p.location = player.getAttribute(DD_KEY_RETURN_LOC,p.location)
}
changeSignsAndAssignTask(player)
}
fun changeSignsAndAssignTask(player: Player){
player.varpManager.get(DD_SIGN_VARP).clearBitRange(0,31)
val tempList = arrayListOf(DD_SIGN_JOG, DD_SIGN_JUMP, DD_SIGN_PUSHUP, DD_SIGN_SITUP).shuffled().toMutableList()
val tempOffsetList = arrayListOf(0,2,4,6).shuffled().toMutableList()
val task = tempList.random()
val taskOffset = tempOffsetList.random()
player.setAttribute(DD_KEY_TASK,task)
player.setAttribute(DD_CORRECT_OFFSET,taskOffset)
tempList.remove(task)
tempOffsetList.remove(taskOffset)
player.varpManager.get(DD_SIGN_VARP).setVarbit(taskOffset,task).send(player)
for(i in 0 until tempList.size){
player.varpManager.get(DD_SIGN_VARP).setVarbit(tempOffsetList[i],tempList[i]).send(player)
}
player.dialogueInterpreter.sendDialogues(NPCs.SERGEANT_DAMIEN_2790,FacialExpression.OLD_NORMAL,when(task){
DD_SIGN_JOG -> "Get over there and jog in place!"
DD_SIGN_JUMP -> "I need 40 jumping jacks stat!"
DD_SIGN_PUSHUP -> "Get over there and give me 20 pushups!"
DD_SIGN_SITUP -> "I need 30 situps pronto!"
else -> "REEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE"
})
player.unlock()
}
fun getOffsetForID(id: Int): Int{
return when(id){
10076 -> 0
10077 -> 2
10078 -> 4
10079 -> 6
else -> 0
}
}
fun getMatTask(id: Int, player: Player): Int{
return player.varpManager.get(DD_SIGN_VARP).getVarbitValue(getOffsetForID(id))
}
fun cleanup(player: Player){
player.removeLogoutListener("drilldemon")
player.properties.teleportLocation = player.getAttribute(DD_KEY_RETURN_LOC)
player.removeAttribute(DD_KEY_NPC)
player.removeAttribute(DD_KEY_RETURN_LOC)
player.removeAttribute(DD_KEY_TASK)
player.removeAttribute(DD_CORRECT_OFFSET)
player.removeAttribute(DD_CORRECT_COUNTER)
}
fun animationForTask(task: Int): Animation {
return when(task){
DD_SIGN_SITUP -> Animation(2763)
DD_SIGN_PUSHUP -> Animation(2762)
DD_SIGN_JUMP -> Animation(2761)
DD_SIGN_JOG -> Animation(2764)
else -> Animation(-1)
}
}
fun reward(player: Player){
val hasHat = player.inventory.contains(Items.CAMO_HELMET_6656,1) || player.bank.contains(Items.CAMO_HELMET_6656,1) || player.equipment.contains(Items.CAMO_HELMET_6656,1)
val hasShirt = player.inventory.contains(Items.CAMO_TOP_6654,1) || player.bank.contains(Items.CAMO_TOP_6654,1) || player.equipment.contains(Items.CAMO_TOP_6654,1)
val hasPants = player.inventory.contains(Items.CAMO_BOTTOMS_6655,1) || player.bank.contains(Items.CAMO_BOTTOMS_6655,1) || player.equipment.contains(Items.CAMO_BOTTOMS_6655,1)
val reward = if(!hasHat){
Item(Items.CAMO_HELMET_6656)
} else if(!hasShirt){
Item(Items.CAMO_TOP_6654)
} else if(!hasPants){
Item(Items.CAMO_BOTTOMS_6655)
} else {
Item(Items.COINS_995,500)
}
if(!player.inventory.add(reward)){
GroundItemManager.create(reward,player)
}
}
}
@@ -0,0 +1,29 @@
package rs09.game.content.ame.events.drilldemon
import core.game.content.dialogue.DialoguePlugin
import core.game.node.entity.player.Player
import core.plugin.Initializable
import org.rs09.consts.NPCs
import rs09.tools.END_DIALOGUE
@Initializable
class SeargentDamienDefaultPlugin(player: Player? = null) : DialoguePlugin(player) {
override fun newInstance(player: Player?): DialoguePlugin {
return SeargentDamienDefaultPlugin(player)
}
override fun open(vararg args: Any?): Boolean {
npc("GET BACK TO WORK MAGGOT!")
stage = END_DIALOGUE
return true
}
override fun handle(interfaceId: Int, buttonId: Int): Boolean {
return true
}
override fun getIds(): IntArray {
return intArrayOf(NPCs.SERGEANT_DAMIEN_2790)
}
}
@@ -0,0 +1,53 @@
package rs09.game.content.ame.events.drilldemon
import core.game.content.dialogue.FacialExpression
import core.game.system.task.Pulse
import rs09.game.content.dialogue.DialogueFile
import rs09.tools.END_DIALOGUE
import rs09.tools.START_DIALOGUE
class SeargentDamienDialogue(val isCorrect: Boolean = false) : DialogueFile() {
override fun handle(componentID: Int, buttonID: Int) {
var correctAmt = player!!.getAttribute(DrillDemonUtils.DD_CORRECT_COUNTER,0)
if(correctAmt == 4 && player!!.antiMacroHandler.event == null) {
when(stage){
0 -> npc(FacialExpression.OLD_NORMAL,"My god you actually did it, you limp","wristed worm-bodied MAGGOT! Take this","and get out of my sight.").also { stage++ }
1 -> {
end()
DrillDemonUtils.cleanup(player!!)
player!!.pulseManager.run(object : Pulse(){
override fun pulse(): Boolean {
DrillDemonUtils.reward(player!!)
return true
}
})
}
}
} else if(player!!.antiMacroHandler.event == null){
when(stage){
START_DIALOGUE -> if(isCorrect) npc(FacialExpression.OLD_NORMAL,"Good! Now...").also { stage++ } else npc(FacialExpression.OLD_ANGRY1,"WRONG, MAGGOT!").also { stage++ }
1 -> {
end()
DrillDemonUtils.changeSignsAndAssignTask(player!!)
}
}
} else {
when(stage){
START_DIALOGUE -> npc(FacialExpression.OLD_NORMAL,"Would you like to come work out?").also { stage++ }
1 -> options("Yes, please.", "No, thanks.").also { stage++ }
2 -> when(buttonID){
1 -> {
end()
DrillDemonUtils.teleport(player!!)
player!!.antiMacroHandler.event.terminate()
stage = END_DIALOGUE
}
2 -> {
player!!.antiMacroHandler.event.terminate()
stage = END_DIALOGUE
}
}
}
}
}
}
@@ -0,0 +1,26 @@
package rs09.game.content.ame.events.drilldemon
import core.game.node.entity.npc.NPC
import core.tools.RandomFunction
import org.rs09.consts.NPCs
import rs09.game.content.ame.RandomEventNPC
import rs09.game.content.global.WeightBasedTable
class SeargentDamienNPC(override var loot: WeightBasedTable? = null) : RandomEventNPC(NPCs.SERGEANT_DAMIEN_2790) {
override fun init() {
super.init()
sendChat(player.username.capitalize() + "! Drop and give me 20!")
}
override fun tick() {
super.tick()
if(RandomFunction.random(1,10) == 5){
sendChat(player.username.capitalize() + "! Drop and give me 20!")
}
}
override fun talkTo(npc: NPC) {
player.dialogueInterpreter.open(SeargentDamienDialogue(),npc)
}
}
@@ -0,0 +1,41 @@
package rs09.game.content.ame.events.sandwichlady
import core.cache.def.impl.ItemDefinition
import core.game.component.Component
import core.game.node.entity.combat.ImpactHandler
import core.game.node.item.GroundItemManager
import core.game.node.item.Item
import rs09.game.content.dialogue.DialogueFile
import rs09.tools.END_DIALOGUE
class SandwichLadyDialogue(val isChoice: Boolean) : DialogueFile() {
val SANDWICH_INTERFACE = 297
override fun handle(componentID: Int, buttonID: Int) {
val assigned = player!!.getAttribute("sandwich-lady:item",0)
val choice = player!!.getAttribute("sandwich-lady:choice",0)
if(!isChoice) {
when (stage) {
0 -> npc("Have a ${ItemDefinition.forId(assigned).name.toLowerCase()}, dear.").also { stage++ }
1 -> {
end()
player!!.interfaceManager.open(Component(SANDWICH_INTERFACE))
}
}
} else {
when(stage){
0 -> if(choice != assigned){
npc!!.sendChat("That's not what I said you could have!")
player!!.impactHandler.manualHit(npc,3,ImpactHandler.HitsplatType.NORMAL)
player!!.antiMacroHandler.event.terminate()
} else {
npc("Here you are, dear. I hope you enjoy it!")
if(!player!!.inventory.add(Item(assigned))){
GroundItemManager.create(Item(assigned),player)
}
player!!.antiMacroHandler.event.terminate()
stage = END_DIALOGUE
}
}
}
}
}
@@ -1,6 +1,5 @@
package rs09.game.content.ame.events
package rs09.game.content.ame.events.sandwichlady
import core.game.node.item.GroundItemManager
import core.game.node.item.Item
import org.rs09.consts.Items
import rs09.game.interaction.InterfaceListener
@@ -30,12 +29,9 @@ class SandwichLadyInterface : InterfaceListener(){
else -> {Item(baguette)}
}
if(!player.inventory.add(item)){
GroundItemManager.create(item,player)
}
player.setAttribute("sandwich-lady:choice",item.id)
player.interfaceManager.close()
player.antiMacroHandler.event.terminate()
player.dialogueInterpreter.open(SandwichLadyDialogue(true),player.antiMacroHandler.event)
return@on true
}
}
@@ -0,0 +1,36 @@
package rs09.game.content.ame.events.sandwichlady
import core.game.node.entity.npc.NPC
import core.tools.RandomFunction
import org.rs09.consts.Items
import org.rs09.consts.NPCs
import rs09.game.content.ame.RandomEventNPC
import rs09.game.content.global.WeightBasedTable
class SandwichLadyRENPC(override var loot: WeightBasedTable? = null) : RandomEventNPC(NPCs.SANDWICH_LADY_3117) {
val phrases = arrayOf("Hello, @name, can you hear me?","Sandwiches, @name!","Are you ignoring me @name??","Yoohoo! Sandwiches, @name!","Hello, @name?", "Come get your sandwiches @name!", "How could you ignore me like this @name?!", "Do you even want your sandwiches, @name?")
var assigned_item = 0
val items = arrayOf(Items.BAGUETTE_6961,Items.TRIANGLE_SANDWICH_6962,Items.SQUARE_SANDWICH_6965,Items.ROLL_6963,Items.MEAT_PIE_2327,Items.KEBAB_1971,Items.CHOCOLATE_BAR_1973)
override fun tick() {
if(RandomFunction.random(1,15) == 5){
sendChat(phrases.random().replace("@name",player.name.capitalize()))
}
super.tick()
}
override fun init() {
super.init()
assignItem()
sendChat(phrases.random().replace("@name",player.name.capitalize()))
}
fun assignItem(){
assigned_item = items.random()
player.setAttribute("sandwich-lady:item",assigned_item)
}
override fun talkTo(npc: NPC) {
player.dialogueInterpreter.open(SandwichLadyDialogue(false),npc)
}
}
@@ -0,0 +1,22 @@
package rs09.game.content.quest.members.waterfall
import core.game.world.map.Location
import org.rs09.consts.NPCs
import rs09.game.interaction.InteractionListener
class WaterfallListeners : InteractionListener(){
val HUDON = NPCs.HUDON_305
override fun defineListeners() {
on(HUDON,NPC,"talk-to"){player, node ->
player.dialogueInterpreter.open(HUDON,node.asNpc())
return@on true
}
}
override fun defineDestinationOverrides() {
setDest(NPC,HUDON){
return@setDest Location.create(2512, 3481, 0)
}
}
}
@@ -2,6 +2,7 @@ package rs09.game.interaction.npc
import core.game.node.entity.npc.NPC
import rs09.game.content.activity.gnomecooking.*
import rs09.game.content.ame.RandomEvents
import rs09.game.interaction.InteractionListener
/**
@@ -14,6 +15,14 @@ class NPCTalkListener : InteractionListener() {
on(NPC,"talk-to","talk"){player,node ->
val npc = node.asNpc()
if(RandomEvents.randomIDs.contains(node.id)){
if(player.antiMacroHandler.event == null || player.antiMacroHandler.event.id != node.id){
player.sendMessage("They aren't interested in talking to you.")
} else {
player.antiMacroHandler.event.talkTo(node.asNpc())
}
return@on true
}
if (!npc.getAttribute("facing_booth", false)) {
npc.faceLocation(player.location)
}
@@ -290,13 +290,13 @@ class PlayerSaver (val player: Player){
}
fun saveAntiMacroHandler(root: JSONObject){
if(player.antiMacroHandler.isSaveRequired){
/*if(player.antiMacroHandler.isSaveRequired){
val antiMacroEvent = JSONObject()
if(player.antiMacroHandler.hasEvent()){
antiMacroEvent.put("eventName",player.antiMacroHandler.event.name)
root.put("antiMacroEvent",antiMacroEvent)
}
}
}*/
}
fun saveStateManager(root: JSONObject){
@@ -1,10 +1,12 @@
package rs09.game.node.entity.state.newsys.states
import core.game.node.entity.player.Player
import rs09.game.node.entity.state.newsys.State
import core.game.system.task.Pulse
import org.json.simple.JSONObject
import rs09.game.node.entity.state.newsys.PlayerState
import rs09.game.node.entity.state.newsys.State
@PlayerState("skull")
class SkulledState(player: Player? = null) : State(player) {
var ticksLeft = 2000
@@ -18,6 +18,7 @@ import core.tools.StringUtils
import org.rs09.consts.Components
import rs09.ServerConstants
import rs09.game.content.activity.fishingtrawler.TrawlerLoot
import rs09.game.content.ame.RandomEvents
import rs09.game.ge.OfferManager
import rs09.game.node.entity.state.newsys.states.FarmingState
import rs09.game.system.SystemLogger
@@ -454,5 +455,10 @@ class MiscCommandSet : CommandSet(Command.Privilege.ADMIN){
bin.finishedTime = System.currentTimeMillis()
}
}
define("testlady",Command.Privilege.ADMIN){player,_ ->
player.antiMacroHandler.event = RandomEvents.DRILL_DEMON.npc.create(player,null)
player.antiMacroHandler.event.init()
}
}
}