Repository reorganisation

Unified kotlin and java into just src/main
Unified the rs09 and core packages
Took all content out of the core package, and placed it into the new content package
Reorganised all source code relating to content to be easier to find and explore
This commit is contained in:
Ceikry
2023-01-26 13:59:28 +00:00
committed by Ryan
parent e4b799c44a
commit a100affda2
3156 changed files with 24205 additions and 30585 deletions
@@ -0,0 +1,99 @@
package content.global.ame
import core.api.Commands
import core.api.LoginListener
import core.game.event.EventHook
import core.game.event.TickEvent
import core.api.getAttribute
import core.api.setAttribute
import core.game.node.entity.Entity
import core.game.node.entity.player.Player
import core.game.world.map.zone.ZoneRestriction
import core.tools.RandomFunction
import core.api.Event
import core.tools.SystemLogger
import core.game.system.command.Privilege
import core.game.world.GameWorld
import core.game.world.repository.Repository
import kotlin.random.Random
class RandomEventManager(val player: Player? = null) : LoginListener, EventHook<TickEvent>, Commands {
var event: content.global.ame.RandomEventNPC? = null
var enabled: Boolean = false
var nextSpawn = 0
val skills = arrayOf("WoodcuttingSkillPulse","FishingPulse","MiningSkillPulse","BoneBuryingOptionPlugin")
override fun login(player: Player) {
if(player.isArtificial) return
val instance = content.global.ame.RandomEventManager(player)
player.hook(Event.Tick, instance)
setAttribute(player, "random-manager", instance)
instance.rollNextSpawn()
instance.enabled = true
SystemLogger.logRE("Initialized REManager for ${player.username}.")
}
override fun process(entity: Entity, event: TickEvent) {
if (GameWorld.ticks > nextSpawn && getAttribute(player!!, "tutorial:complete", false)) fireEvent()
}
fun fireEvent() {
if(!enabled){
rollNextSpawn()
return
}
if (player!!.zoneMonitor.isRestricted(ZoneRestriction.RANDOM_EVENTS)) {
nextSpawn = GameWorld.ticks + 3000
return
}
if (getAttribute<content.global.ame.RandomEventNPC?>(player, "re-npc", null) != null) return
val currentAction = player.pulseManager.current?.toString() ?: "None"
val ame: content.global.ame.RandomEvents = if(currentAction.contains("WoodcuttingSkillPulse") && Random.nextBoolean()){
content.global.ame.RandomEvents.TREE_SPIRIT
} else if(currentAction.contains("FishingPulse") && Random.nextBoolean()){
content.global.ame.RandomEvents.RIVER_TROLL
} else if(currentAction.contains("MiningSkillPulse") && Random.nextBoolean()){
content.global.ame.RandomEvents.ROCK_GOLEM
} else if(currentAction.contains("BoneBuryingOptionPlugin") && Random.nextBoolean()){
content.global.ame.RandomEvents.SHADE
} else {
content.global.ame.RandomEvents.values().filter { it.type != "skill" }.random()
}
event = ame.npc.create(player,ame.loot,ame.type)
if (event!!.spawnLocation == null) {
nextSpawn = GameWorld.ticks + 3000
SystemLogger.logWarn(this::class.java, "Tried to spawn random event for ${player.username} but spawn location was null!")
return
}
event!!.init()
rollNextSpawn()
SystemLogger.logRE("Fired ${event!!.name} for ${player.username}")
}
private fun rollNextSpawn() {
nextSpawn = GameWorld.ticks + RandomFunction.random(content.global.ame.RandomEventManager.Companion.MIN_DELAY_TICKS, content.global.ame.RandomEventManager.Companion.MAX_DELAY_TICKS)
}
override fun defineCommands() {
define("targeted-ame", Privilege.ADMIN, "targeted-ame username", "Summons a random for the given user") {player, args ->
val username = args[1]
val target = Repository.getPlayerByName(username)
if (target == null)
reject(player, "Unable to find player $username!")
content.global.ame.RandomEventManager.Companion.getInstance(target!!)?.fireEvent()
}
}
companion object {
const val AVG_DELAY_TICKS = 6000 // 60 minutes
const val MIN_DELAY_TICKS = content.global.ame.RandomEventManager.Companion.AVG_DELAY_TICKS / 2
const val MAX_DELAY_TICKS = content.global.ame.RandomEventManager.Companion.MIN_DELAY_TICKS + content.global.ame.RandomEventManager.Companion.AVG_DELAY_TICKS // window of 60 min centered on 60 min (30 to 90 min)
@JvmStatic fun getInstance(player: Player): content.global.ame.RandomEventManager?
{
return getAttribute(player, "random-manager", null)
}
}
}
@@ -0,0 +1,117 @@
package content.global.ame
import content.global.ame.events.MysteriousOldManNPC
import core.api.poofClear
import core.game.interaction.MovementPulse
import core.game.node.entity.impl.PulseType
import core.game.node.entity.npc.NPC
import core.game.node.entity.player.Player
import core.game.node.item.Item
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 core.integrations.discord.Discord
import core.api.utils.WeightBasedTable
import core.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 finalized = false
var timerPaused = false
var ticksLeft = secondsToTicks(180)
open fun create(player: Player, loot: WeightBasedTable? = null, type: String = ""): RandomEventNPC {
val event = this::class.createInstance()
if (event is MysteriousOldManNPC) event.type = type
event.loot = loot
event.player = player
event.spawnLocation = RegionManager.getSpawnLocation(player, this)
return event
}
open fun terminate() {
finalized = true
pulseManager.clear(PulseType.STANDARD)
content.global.ame.RandomEventManager.getInstance(player)?.event = null
if (initialized) {
poofClear(this)
}
}
open fun follow() {
pulseManager.run((object : MovementPulse(this, player, Pathfinder.DUMB) {
override fun pulse(): Boolean {
face(player)
return false
}
}), PulseType.STANDARD)
}
override fun tick() {
super.tick()
if(player.getAttribute<RandomEventNPC?>("re-npc", null) != this){
terminate()
return
}
if (!player.getAttribute("random:pause", false)) {
ticksLeft--
}
if (!pulseManager.hasPulseRunning() && !finalized) {
follow()
}
if (!player.isActive || !player.location.withinDistance(location, 10)) {
terminate()
}
if (ticksLeft <= 0 && initialized) {
onTimeUp()
initialized = false
}
}
override fun init() {
initialized = true
finalized = false
timerPaused = false
spawnLocation ?: terminate()
location = spawnLocation
player.setAttribute("re-npc", this)
super.init()
}
open fun onTimeUp() {
noteAndTeleport()
terminate()
}
fun noteAndTeleport() {
for (item in player.inventory.toArray()) {
if (item == null) continue
if (item.definition.isUnnoted) {
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)
Discord.postPlayerAlert(player.username, "Ignored Random")
}
override fun clear() {
super.clear()
if(player.getAttribute<RandomEventNPC?>("re-npc", null) == this) player.removeAttribute("re-npc")
}
abstract fun talkTo(npc: NPC)
}
@@ -0,0 +1,60 @@
package content.global.ame
import org.rs09.consts.Items
import content.global.ame.events.MysteriousOldManNPC
import content.global.ame.events.certer.CerterNPC
import content.global.ame.events.drilldemon.SeargentDamienNPC
import content.global.ame.events.evilchicken.EvilChickenNPC
import content.global.ame.events.genie.GenieNPC
import content.global.ame.events.rivertroll.RiverTrollRENPC
import content.global.ame.events.rockgolem.RockGolemRENPC
import content.global.ame.events.sandwichlady.SandwichLadyRENPC
import content.global.ame.events.shade.ShadeRENPC
import content.global.ame.events.treespirit.TreeSpiritRENPC
import content.global.ame.events.zombie.ZombieRENPC
import core.api.utils.WeightBasedTable
import core.api.utils.WeightedItem
enum class RandomEvents(val npc: RandomEventNPC, val loot: WeightBasedTable? = null) {
SANDWICH_LADY(SandwichLadyRENPC()),
GENIE(GenieNPC()),
CERTER(CerterNPC(), WeightBasedTable.create(
WeightedItem(Items.UNCUT_SAPPHIRE_1623,1,1,3.4),
WeightedItem(Items.KEBAB_1971,1,1,1.7),
WeightedItem(Items.UNCUT_EMERALD_1621,1,1,1.7),
WeightedItem(Items.SPINACH_ROLL_1969,1,1,1.5),
WeightedItem(Items.COINS_995,80,80,1.1),
WeightedItem(Items.COINS_995,160,160,1.1),
WeightedItem(Items.COINS_995,320,320,1.1),
WeightedItem(Items.COINS_995,480,480,1.1),
WeightedItem(Items.COINS_995,640,640,1.1),
WeightedItem(Items.UNCUT_RUBY_1619,1,1,0.86),
WeightedItem(Items.COINS_995,240,240,0.65),
WeightedItem(Items.COSMIC_TALISMAN_1454,1,1,0.43),
WeightedItem(Items.UNCUT_DIAMOND_1617,1,1,0.22),
WeightedItem(Items.TOOTH_HALF_OF_A_KEY_985,1,1,0.1),
WeightedItem(Items.LOOP_HALF_OF_A_KEY_987,1,1,0.1)
)),
DRILL_DEMON(SeargentDamienNPC()),
EVIL_CHICKEN(EvilChickenNPC()),
SURPRISE_EXAM(MysteriousOldManNPC(),"sexam"),
TREE_SPIRIT(TreeSpiritRENPC(),"skill"),
RIVER_TROLL(RiverTrollRENPC(),"skill"),
ROCK_GOLEM(RockGolemRENPC(),"skill"),
SHADE(ShadeRENPC(),"skill"),
ZOMBIE(ZombieRENPC(),"skill");
var type: String = ""
private set
constructor(npc: RandomEventNPC, type: String) : this(npc,null){
this.type = type
}
companion object {
@JvmField
val randomIDs = values().map { it.npc.id }.toList()
}
}
@@ -0,0 +1,40 @@
package content.global.ame.events
import core.game.node.entity.player.Player
import content.global.ame.events.supriseexam.SurpriseExamUtils
import core.game.dialogue.DialogueFile
class MysteriousOldManDialogue(val type: String) : DialogueFile() {
val CHOICE_STAGE = 50000
override fun handle(componentID: Int, buttonID: Int) {
if(type == "sexam" && stage < CHOICE_STAGE){
npc("Would you like to come do a surprise exam?")
stage = CHOICE_STAGE
}
else if(stage >= CHOICE_STAGE){
when(stage) {
CHOICE_STAGE -> options("Yeah, sure!", "No, thanks.").also { stage++ }
CHOICE_STAGE.substage(1) -> when(buttonID){
1 -> {
end()
teleport(player!!,type)
content.global.ame.RandomEventManager.getInstance(player!!)?.event?.terminate()
}
2 -> {
end()
content.global.ame.RandomEventManager.getInstance(player!!)?.event?.terminate()
}
}
}
}
}
fun teleport(player: Player,type: String){
when(type){
"sexam" -> SurpriseExamUtils.teleport(player)
}
}
}
@@ -0,0 +1,31 @@
package content.global.ame.events
import content.global.ame.RandomEventNPC
import core.game.node.entity.npc.NPC
import core.tools.RandomFunction
import org.rs09.consts.NPCs
import core.api.utils.WeightBasedTable
class MysteriousOldManNPC(var type: String = "", override var loot: WeightBasedTable? = null) : RandomEventNPC(NPCs.MYSTERIOUS_OLD_MAN_410) {
override fun init() {
super.init()
sayLine()
}
override fun tick() {
super.tick()
if(RandomFunction.random(1,10) == 5) sayLine()
}
fun sayLine() {
when(type){
"sexam" -> sendChat("Surprise exam, ${player.username.capitalize()}!")
}
}
override fun talkTo(npc: NPC) {
when(type){
"sexam" -> player.dialogueInterpreter.open(MysteriousOldManDialogue("sexam"),this.asNpc())
}
}
}
@@ -0,0 +1,59 @@
package content.global.ame.events.certer
import core.api.addItemOrDrop
import core.game.component.Component
import core.game.node.entity.impl.PulseType
import core.game.node.entity.player.link.emote.Emotes
import core.game.dialogue.DialogueFile
import core.tools.END_DIALOGUE
class CerterDialogue(val initial: Boolean) : DialogueFile() {
val CERTER_INTERFACE = 184
override fun handle(componentID: Int, buttonID: Int) {
if (initial && !player!!.getAttribute("certer:reward", false)) {
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 {
player!!.setAttribute("random:pause", true)
val isCorrect = player!!.getAttribute("certer:correct", false)
val receivedReward = player!!.getAttribute("certer:reward", false)
if (receivedReward == true) {
stage = 1
}
when (stage) {
0 -> if (!isCorrect) {
npc("Sorry, I don't think so.").also {
player!!.setAttribute("certer:reward", true)
stage = END_DIALOGUE
content.global.ame.RandomEventManager.getInstance(player!!)?.event?.terminate()
}
} else {
npc("Thank you, I hope you like your present. I must be", "leaving now though.").also {
player!!.setAttribute("certer:reward", true)
stage = END_DIALOGUE
content.global.ame.RandomEventManager.getInstance(player!!)!!.event!!.loot!!.roll().forEach { addItemOrDrop(player!!, it.id, it.amount) }
}
}
}
}
}
override fun end() {
super.end()
if (player!!.getAttribute("certer:reward", false)) {
// Remove movement pulse to stop following player
npc!!.pulseManager.clear(PulseType.STANDARD)
// Wave goodbye
npc!!.animate(Emotes.WAVE.animation)
// Terminate the event
content.global.ame.RandomEventManager.getInstance(player!!)?.event?.terminate()
} else {
player!!.setAttribute("random:pause", false)
}
}
}
@@ -0,0 +1,85 @@
package content.global.ame.events.certer
import content.global.ame.RandomEventManager
import core.game.node.entity.player.Player
import core.game.node.item.Item
import org.rs09.consts.Items
import core.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(
/*
* NOTE: We use these "NULL" items to get their model id + zoom values.
* These were the actual items used by this random event before they
* decided to swap over to using model ids instead.
*/
Items.BOWL_1923 to "A bowl.",
Items.NULL_6189 to "A fish.",
Items.NULL_6190 to "A bass.",
Items.NULL_6191 to "A sword.",
Items.NULL_6192 to "A battleaxe.",
Items.NULL_6193 to "A helmet.",
Items.NULL_6194 to "A kiteshield.",
Items.NULL_6195 to "A pair of shears.",
Items.NULL_6196 to "A shovel.",
Items.NULL_6197 to "A ring.",
Items.NULL_6198 to "A necklace."
)
val falseOptions = arrayOf("An axe.", "An arrow.", "A pair of boots.", "A pair of gloves.", "A staff.", "A bow.", "A feather.", "The disenfrachaised youth of 1940's Columbia.")
override fun defineInterfaceListeners() {
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), RandomEventManager.getInstance(player)!!.event?.asNpc())
return@on true
}
onOpen(CERTER_INTERFACE) { player, _ ->
generateOptions(player)
return@onOpen true
}
onClose(CERTER_INTERFACE) { player, _ ->
player.setAttribute("random:pause", false)
return@onClose true
}
}
fun generateOptions(player: Player) {
val correct = items.keys.random()
val indexes = arrayListOf(1, 2, 3)
val correctIndex = indexes.random()
val correctItem = Item(correct).definition
val iFaceModelId = correctItem.interfaceModelId
val iFaceZoom = correctItem.modelZoom
indexes.remove(correctIndex)
player.setAttribute("certer:correctIndex", correctIndex)
player.packetDispatch.sendString(items[correct], CERTER_INTERFACE, optionFromIndex(correctIndex))
val tempOptions = falseOptions.toMutableList()
val false1 = tempOptions.random()
tempOptions.remove(false1)
val false2 = tempOptions.random()
player.packetDispatch.sendString(false1, CERTER_INTERFACE, optionFromIndex(indexes[0]))
player.packetDispatch.sendString(false2, CERTER_INTERFACE, optionFromIndex(indexes[1]))
player.packetDispatch.sendModelOnInterface(iFaceModelId, CERTER_INTERFACE, ITEM_CHILD, iFaceZoom)
}
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,50 @@
package content.global.ame.events.certer
import core.game.node.entity.npc.NPC
import core.game.node.entity.player.link.emote.Emotes
import core.tools.RandomFunction
import org.rs09.consts.NPCs
import content.global.ame.RandomEventNPC
import core.api.animate
import core.api.utils.WeightBasedTable
class CerterNPC(override var loot: WeightBasedTable? = null) : RandomEventNPC(NPCs.GILES_2538) {
lateinit var pName: String
lateinit var phrases: Array<String>
override fun tick() {
// Don't speak if we have the interface opened
if (!timerPaused) {
// Over allotted time phrase
if (ticksLeft <= 2) {
player.lock(2)
sendChat(phrases[4])
// Say a phrase every 20 ticks starting at 280 ticks
// as to not interfere with the init chat phrase
} else if (ticksLeft <= 280 && ticksLeft % 20 == 0) {
sendChat(phrases[RandomFunction.random(1, 3)])
}
}
super.tick()
}
override fun talkTo(npc: NPC) {
player.setAttribute("random:pause", true)
player.dialogueInterpreter.open(CerterDialogue(true),npc)
}
override fun init() {
super.init()
pName = player.username.capitalize()
phrases = arrayOf("Greetings $pName, I need your help.",
"ehem... Hello $pName, please talk to me!",
"Hello, are you there $pName?",
"It's really rude to ignore someone, $pName!",
"No-one ignores me!")
player.setAttribute("random:pause", false)
player.setAttribute("certer:reward", false)
sendChat(phrases[0])
animate(this, Emotes.BOW.animation, true)
}
}
@@ -0,0 +1,50 @@
package content.global.ame.events.drilldemon
import core.game.node.entity.npc.NPC
import core.game.system.task.Pulse
import org.rs09.consts.NPCs
import core.game.interaction.InteractionListener
import core.game.interaction.IntType
class DrillDemonListeners : InteractionListener {
val MATS = intArrayOf(10076,10077,10078,10079)
override fun defineListeners() {
on(MATS, IntType.SCENERY, "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,120 @@
package content.global.ame.events.drilldemon
import core.api.*
import core.game.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.interfaceManager.closeDefaultTabs()
player.packetDispatch.sendInterfaceConfig(548, 69, true)
player.packetDispatch.sendInterfaceConfig(746, 12, true)
registerLogoutListener(player, "drilldemon"){p ->
teleport(p, 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, core.game.dialogue.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)) ?: 0
}
fun cleanup(player: Player){
clearLogoutListener(player, "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)
player.interfaceManager.openDefaultTabs()
player.packetDispatch.sendInterfaceConfig(548, 69, false)
player.packetDispatch.sendInterfaceConfig(746, 12, false)
}
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 content.global.ame.events.drilldemon
import core.game.dialogue.DialoguePlugin
import core.game.node.entity.player.Player
import core.plugin.Initializable
import org.rs09.consts.NPCs
import core.tools.END_DIALOGUE
@Initializable
class SeargentDamienDefaultPlugin(player: Player? = null) : core.game.dialogue.DialoguePlugin(player) {
override fun newInstance(player: Player?): core.game.dialogue.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,55 @@
package content.global.ame.events.drilldemon
import core.game.dialogue.FacialExpression
import core.game.system.task.Pulse
import core.game.dialogue.DialogueFile
import core.tools.END_DIALOGUE
import core.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 && content.global.ame.RandomEventManager.getInstance(player!!)!!.event == null) {
when(stage){
0 -> npc(core.game.dialogue.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()
player!!.unlock()
DrillDemonUtils.cleanup(player!!)
player!!.pulseManager.run(object : Pulse(2){
override fun pulse(): Boolean {
DrillDemonUtils.reward(player!!)
return true
}
})
}
}
} else if(content.global.ame.RandomEventManager.getInstance(player!!)!!.event == null){
when(stage){
START_DIALOGUE -> if(isCorrect) npc(core.game.dialogue.FacialExpression.OLD_NORMAL,"Good! Now...").also { stage++ } else npc(core.game.dialogue.FacialExpression.OLD_ANGRY1,"WRONG, MAGGOT!").also { stage++ }
1 -> {
end()
DrillDemonUtils.changeSignsAndAssignTask(player!!)
}
}
} else {
when(stage){
START_DIALOGUE -> npc(core.game.dialogue.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!!)
content.global.ame.RandomEventManager.getInstance(player!!)!!.event?.terminate()
stage = END_DIALOGUE
}
2 -> {
end()
content.global.ame.RandomEventManager.getInstance(player!!)!!.event?.terminate()
stage = END_DIALOGUE
}
}
}
}
}
}
@@ -0,0 +1,26 @@
package content.global.ame.events.drilldemon
import core.game.node.entity.npc.NPC
import core.tools.RandomFunction
import org.rs09.consts.NPCs
import content.global.ame.RandomEventNPC
import core.api.utils.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,45 @@
package content.global.ame.events.evilchicken
import core.api.getWorldTicks
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 content.global.ame.RandomEventNPC
import core.api.utils.WeightBasedTable
import java.lang.Integer.max
val ids = 2463..2468
class EvilChickenNPC(override var loot: WeightBasedTable? = null) : RandomEventNPC(2463) {
val phrases = arrayOf("Bwuk","Bwuk bwuk bwuk","Flee from me, @name!","Begone, @name!","Bwaaaauuuk bwuk bwuk","MUAHAHAHAHAAA!")
override fun talkTo(npc: NPC) {}
override fun init() {
super.init()
val index = max(0, (player.properties.combatLevel / 20) - 1)
val id = ids.toList()[index]
this.transform(id)
this.attack(player)
sendChat(phrases.random().replace("@name",player.name.capitalize()))
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() {
if(!player.location.withinDistance(this.location,8)){
this.terminate()
}
if(getWorldTicks() % 10 == 0){
sendChat(phrases.random().replace("@name",player.name.capitalize()))
}
super.tick()
if(!player.viewport.currentPlane.npcs.contains(this)) this.clear()
}
}
@@ -0,0 +1,16 @@
package content.global.ame.events.genie
import core.api.*
import core.game.dialogue.FacialExpression
import core.game.dialogue.DialogueFile
import core.tools.END_DIALOGUE
class GenieDialogue : DialogueFile() {
override fun handle(componentID: Int, buttonID: Int) {
val assigned = player!!.getAttribute("genie:item",0)
npcl(core.game.dialogue.FacialExpression.NEUTRAL, "Ah, so you are there, ${player!!.name.capitalize()}. I'm so glad you summoned me. Please take this lamp and make your wish.")
addItemOrDrop(player!!, assigned)
content.global.ame.RandomEventManager.getInstance(player!!)!!.event?.terminate()
stage = END_DIALOGUE
}
}
@@ -0,0 +1,36 @@
package content.global.ame.events.genie
import core.game.node.entity.npc.NPC
import core.tools.RandomFunction
import org.rs09.consts.Items
import org.rs09.consts.NPCs
import content.global.ame.RandomEventNPC
import core.api.utils.WeightBasedTable
class GenieNPC(override var loot: WeightBasedTable? = null) : RandomEventNPC(NPCs.GENIE_409) {
val phrases = arrayOf("Greetings, @name!","Ehem... Master @name?","Are you there, Master @name?","No one ignores me!")
var assigned_item = 0
val items = arrayOf(Items.LAMP_2528)
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("genie:item",assigned_item)
}
override fun talkTo(npc: NPC) {
player.dialogueInterpreter.open(GenieDialogue(),npc)
}
}
@@ -0,0 +1,33 @@
package content.global.ame.events.rivertroll
import core.game.node.entity.Entity
import core.game.node.entity.npc.NPC
import content.global.ame.RandomEventNPC
import core.api.utils.WeightBasedTable
import java.lang.Integer.max
val ids = 391..396
class RiverTrollRENPC(override var loot: WeightBasedTable? = null) : RandomEventNPC(391){
override fun talkTo(npc: NPC) {}
override fun init() {
super.init()
val index = max(0, (player.properties.combatLevel / 20) - 1)
val id = ids.toList()[index]
this.transform(id)
this.attack(player)
sendChat("Fishies be mine, leave dem fishies!")
this.isRespawn = false
}
override fun finalizeDeath(killer: Entity?) {
super.finalizeDeath(killer)
}
override fun tick() {
if(!player.location.withinDistance(this.location,8)){
this.terminate()
}
super.tick()
if(!player.viewport.currentPlane.npcs.contains(this)) this.clear()
}
}
@@ -0,0 +1,33 @@
package content.global.ame.events.rockgolem
import core.game.node.entity.Entity
import core.game.node.entity.npc.NPC
import content.global.ame.RandomEventNPC
import core.api.utils.WeightBasedTable
import kotlin.math.max
val ids = 413..418
class RockGolemRENPC(override var loot: WeightBasedTable? = null) : RandomEventNPC(413){
override fun talkTo(npc: NPC) {}
override fun init() {
super.init()
val index = max(0,(player.properties.combatLevel / 20) - 1)
val id = ids.toList()[index]
this.transform(id)
this.attack(player)
sendChat("Raarrrgghh! Flee human!")
this.isRespawn = false
}
override fun finalizeDeath(killer: Entity?) {
super.finalizeDeath(killer)
}
override fun tick() {
if(!player.location.withinDistance(this.location,8)){
this.terminate()
}
super.tick()
if(!player.viewport.currentPlane.npcs.contains(this)) this.clear()
}
}
@@ -0,0 +1,41 @@
package content.global.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 core.game.dialogue.DialogueFile
import core.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)
content.global.ame.RandomEventManager.getInstance(player!!)!!.event?.terminate()
} else {
npc("Here you are, dear. I hope you enjoy it!")
if(!player!!.inventory.add(Item(assigned))){
GroundItemManager.create(Item(assigned),player)
}
content.global.ame.RandomEventManager.getInstance(player!!)!!.event?.terminate()
stage = END_DIALOGUE
}
}
}
}
}
@@ -0,0 +1,38 @@
package content.global.ame.events.sandwichlady
import core.game.node.item.Item
import org.rs09.consts.Items
import core.game.interaction.InterfaceListener
class SandwichLadyInterface : InterfaceListener {
val SANDWICH_INTERFACE = 297
val baguette = Items.BAGUETTE_6961
val triangle_sandwich = Items.TRIANGLE_SANDWICH_6962
val sandwich = Items.SQUARE_SANDWICH_6965
val roll = Items.ROLL_6963
val pie = Items.MEAT_PIE_2327
val kebab = Items.KEBAB_1971
val chocobar = Items.CHOCOLATE_BAR_1973
override fun defineInterfaceListeners() {
on(SANDWICH_INTERFACE){player, _, _, buttonID, _, _ ->
val item =
when(buttonID) {
7 -> {Item(baguette)}
8 -> {Item(triangle_sandwich)}
9 -> {Item(sandwich)}
10 -> {Item(roll)}
11 -> {Item(pie)}
12 -> {Item(kebab)}
13 -> {Item(chocobar)}
else -> {Item(baguette)}
}
player.setAttribute("sandwich-lady:choice",item.id)
player.interfaceManager.close()
player.dialogueInterpreter.open(SandwichLadyDialogue(true), content.global.ame.RandomEventManager.getInstance(player)!!.event)
return@on true
}
}
}
@@ -0,0 +1,36 @@
package content.global.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 content.global.ame.RandomEventNPC
import core.api.utils.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,32 @@
package content.global.ame.events.shade
import core.game.node.entity.Entity
import core.game.node.entity.npc.NPC
import content.global.ame.RandomEventNPC
import core.api.utils.WeightBasedTable
val ids = 425..430
class ShadeRENPC(override var loot: WeightBasedTable? = null) : RandomEventNPC(425){
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)
sendChat("Leave this place!")
this.isRespawn = false
}
override fun finalizeDeath(killer: Entity?) {
super.finalizeDeath(killer)
}
override fun tick() {
if(!player.location.withinDistance(this.location,8)){
this.terminate()
}
super.tick()
if(!player.viewport.currentPlane.npcs.contains(this)) this.clear()
}
}
@@ -0,0 +1,65 @@
package content.global.ame.events.supriseexam
import core.game.component.Component
import core.game.dialogue.FacialExpression
import core.game.dialogue.DialogueFile
import core.tools.END_DIALOGUE
class MordautDialogue(val examComplete: Boolean, val questionCorrect: Boolean = false, val fromInterface: Boolean = false) : DialogueFile() {
override fun handle(componentID: Int, buttonID: Int) {
if(examComplete){
if(player!!.getAttribute(SurpriseExamUtils.SE_DOOR_KEY,-1) == -1){
SurpriseExamUtils.pickRandomDoor(player!!)
}
val door = player!!.getAttribute(SurpriseExamUtils.SE_DOOR_KEY,-1)
val doortext = when(door){
2188 -> "red cross"
2189 -> "blue star"
2192 -> "purple circle"
2193 -> "green square"
else -> "REEEEEEEEEEEEEEEE"
}
npc("Please exit through the $doortext door.")
stage = END_DIALOGUE
} else if(fromInterface){
if(questionCorrect){
if(player!!.getAttribute(SurpriseExamUtils.SE_KEY_CORRECT,0) == 3){
player!!.dialogueInterpreter.open(MordautDialogue(true),npc)
} else {
when(stage++){
0 -> npc("Excellent work!")
1 -> npc("Now for another...")
2 -> {
end()
player!!.interfaceManager.open(Component(SurpriseExamUtils.INTERFACE))
}
}
}
} else {
when(stage++){
0 -> npc("I'm afraid that isn't correct.")
1 -> npc("Now for another...")
2 -> {
end()
player!!.interfaceManager.open(Component(SurpriseExamUtils.INTERFACE))
}
}
}
} else {
when(stage++){
0 -> npc("Please answer these questions for me.")
1 -> {
end()
player!!.interfaceManager.open(Component(SurpriseExamUtils.INTERFACE))
}
}
}
}
override fun npc(vararg messages: String?): Component? {
return super.npc(core.game.dialogue.FacialExpression.OLD_NORMAL,*messages)
}
}
@@ -0,0 +1,16 @@
package content.global.ame.events.supriseexam
import core.game.dialogue.DialogueFile
import core.tools.END_DIALOGUE
class SEDoorDialogue(val preExam: Boolean) : DialogueFile() {
override fun handle(componentID: Int, buttonID: Int) {
stage = if(preExam){
dialogue("I should probably speak with Mr. Mordaut first.")
END_DIALOGUE
} else {
dialogue("The door won't budge. Perhaps I should","ask for directions.")
END_DIALOGUE
}
}
}
@@ -0,0 +1,36 @@
package content.global.ame.events.supriseexam
import core.game.node.entity.npc.NPC
import org.rs09.consts.Components
import org.rs09.consts.NPCs
import core.game.interaction.InterfaceListener
class SEPatternInterface : InterfaceListener {
val COMPONENT = Components.PATTERN_NEXT_103
override fun defineInterfaceListeners() {
on(COMPONENT){player, component, opcode, buttonID, slot, itemID ->
val index = buttonID - 10
val correctIndex = player.getAttribute(SurpriseExamUtils.SE_KEY_INDEX,0)
player.interfaceManager.close()
if(index == correctIndex){
player.incrementAttribute(SurpriseExamUtils.SE_KEY_CORRECT)
val done = player.getAttribute(SurpriseExamUtils.SE_KEY_CORRECT,0) == 3
player.dialogueInterpreter.open(MordautDialogue(examComplete = done,questionCorrect = true,fromInterface = true), NPC(NPCs.MR_MORDAUT_6117))
} else {
player.dialogueInterpreter.open(MordautDialogue(examComplete = false,questionCorrect = false,fromInterface = true),NPC(NPCs.MR_MORDAUT_6117))
}
return@on true
}
onOpen(COMPONENT){player, component ->
SurpriseExamUtils.generateInterface(player)
return@onOpen true
}
}
}
@@ -0,0 +1,61 @@
package content.global.ame.events.supriseexam
import core.game.component.Component
import core.game.node.entity.player.Player
import core.game.node.item.Item
import core.game.world.map.Location
import org.rs09.consts.Items
import org.rs09.consts.NPCs
import core.game.interaction.InteractionListener
import core.game.interaction.IntType
import content.global.handlers.iface.ExperienceInterface
class SupriseExamListeners : InteractionListener {
val MORDAUT = NPCs.MR_MORDAUT_6117
val BOOK_OF_KNOWLEDGE = Items.BOOK_OF_KNOWLEDGE_11640
override fun defineListeners() {
on(MORDAUT, IntType.NPC, "talk-to"){ player, node ->
player.faceLocation(Location.create(1886, 5024, 0))
val examComplete = player.getAttribute(SurpriseExamUtils.SE_KEY_CORRECT,0) == 3
player.dialogueInterpreter.open(MordautDialogue(examComplete),node.asNpc())
return@on true
}
on(SurpriseExamUtils.SE_DOORS, IntType.SCENERY, "open"){ player, node ->
val correctDoor = player.getAttribute(SurpriseExamUtils.SE_DOOR_KEY,-1)
if(correctDoor == -1){
player.dialogueInterpreter.open(SEDoorDialogue(true))
return@on true
}
if(node.id == correctDoor){
SurpriseExamUtils.cleanup(player)
return@on true
}
player.dialogueInterpreter.open(SEDoorDialogue(false))
return@on true
}
on(BOOK_OF_KNOWLEDGE, IntType.ITEM, "read"){ player, _ ->
player.setAttribute("caller"){skill: Int,p: Player ->
if(p.inventory.remove(Item(BOOK_OF_KNOWLEDGE))) {
val level = p.skills.getStaticLevel(skill)
val experience = level * 15.0
p.skills.addExperience(skill, experience)
}
}
player.interfaceManager.open(Component(ExperienceInterface.COMPONENT_ID))
return@on true
}
}
override fun defineDestinationOverrides() {
setDest(IntType.NPC,MORDAUT){ _, _ ->
return@setDest Location.create(1886, 5025, 0)
}
}
}
@@ -0,0 +1,84 @@
package content.global.ame.events.supriseexam
import core.api.*
import core.game.node.entity.impl.PulseType
import core.game.node.entity.player.Player
import core.game.node.item.GroundItemManager
import core.game.node.item.Item
import core.game.system.task.Pulse
import core.game.world.map.Location
import org.rs09.consts.Components
import org.rs09.consts.Items
object SurpriseExamUtils {
val SE_KEY_LOC = "supexam:loc"
val SE_KEY_INDEX = "supexam:index"
val SE_LOGOUT_KEY = "suprise_exam"
val SE_DOOR_KEY = "supexam:door"
val INTER_PATTERN_CHILDS = intArrayOf(6,7,8)
val INTER_OPTION_CHILDS = intArrayOf(10,11,12,13)
val SE_DOORS = intArrayOf(2188,2189,2192,2193)
val INTERFACE = Components.PATTERN_NEXT_103
val SE_KEY_CORRECT = "supexam:correct"
val sets = arrayOf(
intArrayOf(Items.GARDENING_TROWEL_5325,Items.SECATEURS_5329,Items.SEED_DIBBER_5343,Items.RAKE_5341),
intArrayOf(Items.SALMON_329,Items.SHARK_385,Items.TROUT_333,Items.SHRIMPS_315),
intArrayOf(Items.BRONZE_SWORD_1277,Items.WOODEN_SHIELD_1171,Items.BRONZE_MED_HELM_1139,Items.ADAMANT_BATTLEAXE_1371),
intArrayOf(Items.FLY_FISHING_ROD_309,Items.BARBARIAN_ROD_11323,Items.SMALL_FISHING_NET_303,Items.HARPOON_311)
)
fun teleport(player: Player){
player.setAttribute(SE_KEY_LOC,player.location)
registerLogoutListener(player, SE_LOGOUT_KEY){p ->
teleport(p, p.getAttribute(SE_KEY_LOC, p.location))
}
player.properties.teleportLocation = Location.create(1886, 5025, 0)
}
fun cleanup(player: Player){
player.properties.teleportLocation = player.getAttribute(SE_KEY_LOC,null)
clearLogoutListener(player, SE_LOGOUT_KEY)
player.removeAttribute(SE_KEY_LOC)
player.removeAttribute(SE_KEY_INDEX)
player.removeAttribute(SE_KEY_CORRECT)
player.pulseManager.run(object : Pulse(2){
override fun pulse(): Boolean {
val reward = Item(Items.BOOK_OF_KNOWLEDGE_11640)
if(!player.inventory.add(reward)){
GroundItemManager.create(reward,player)
}
return true
}
}, PulseType.CUSTOM_1)
}
fun generateInterface(player: Player){
val set = sets.random()
val setIndex = sets.indexOf(set)
val tempList = set.toList().shuffled().toMutableList()
val correctOpt = tempList.random()
val optIndex = tempList.indexOf(correctOpt)
tempList.remove(correctOpt)
for(i in INTER_PATTERN_CHILDS.indices) player.packetDispatch.sendItemOnInterface(tempList[i],1, INTERFACE, INTER_PATTERN_CHILDS[i])
for(i in INTER_OPTION_CHILDS.indices){
if(i == optIndex) player.packetDispatch.sendItemOnInterface(correctOpt,1, INTERFACE, INTER_OPTION_CHILDS[i])
else player.packetDispatch.sendItemOnInterface(getFalseSet(setIndex)[i],1, INTERFACE, INTER_OPTION_CHILDS[i])
}
player.setAttribute(SE_KEY_INDEX,optIndex)
}
fun getFalseSet(trueSetIndex: Int): IntArray{
val tempSets = sets.toMutableList()
tempSets.removeAt(trueSetIndex)
return tempSets.random()
}
fun pickRandomDoor(player: Player){
player.setAttribute(SE_DOOR_KEY, SE_DOORS.random())
}
}
@@ -0,0 +1,33 @@
package content.global.ame.events.treespirit
import core.game.node.entity.Entity
import core.game.node.entity.npc.NPC
import content.global.ame.RandomEventNPC
import core.api.utils.WeightBasedTable
import kotlin.math.max
val ids = 438..443
class TreeSpiritRENPC(override var loot: WeightBasedTable? = null) : RandomEventNPC(438){
override fun talkTo(npc: NPC) {}
override fun init() {
super.init()
val index = max(0,(player.properties.combatLevel / 20) - 1)
val id = ids.toList()[index]
this.transform(id)
this.attack(player)
sendChat("Leave these woods and never return!")
this.isRespawn = false
}
override fun finalizeDeath(killer: Entity?) {
super.finalizeDeath(killer)
}
override fun tick() {
if(!player.location.withinDistance(this.location,8)){
this.terminate()
}
super.tick()
if(!player.viewport.currentPlane.npcs.contains(this)) this.clear()
}
}
@@ -0,0 +1,32 @@
package content.global.ame.events.zombie
import core.game.node.entity.Entity
import core.game.node.entity.npc.NPC
import content.global.ame.RandomEventNPC
import core.api.utils.WeightBasedTable
val ids = 419..424
class ZombieRENPC(override var loot: WeightBasedTable? = null) : RandomEventNPC(419){
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)
sendChat("Brainsssss!")
this.isRespawn = false
}
override fun finalizeDeath(killer: Entity?) {
super.finalizeDeath(killer)
}
override fun tick() {
if(!player.location.withinDistance(this.location,8)){
this.terminate()
}
super.tick()
if(!player.viewport.currentPlane.npcs.contains(this)) this.clear()
}
}