Implemented Freaky Forester random event
Added admin ::freak command to trigger Freaky Forester
This commit is contained in:
@@ -5,6 +5,7 @@ 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.freakyforester.FreakyForesterNPC
|
||||
import content.global.ame.events.genie.GenieNPC
|
||||
import content.global.ame.events.rivertroll.RiverTrollRENPC
|
||||
import content.global.ame.events.rockgolem.RockGolemRENPC
|
||||
@@ -40,6 +41,7 @@ enum class RandomEvents(val npc: RandomEventNPC, val loot: WeightBasedTable? = n
|
||||
DRILL_DEMON(npc = SeargentDamienNPC()),
|
||||
EVIL_CHICKEN(npc = EvilChickenNPC()),
|
||||
SURPRISE_EXAM(npc = MysteriousOldManNPC(), type = "sexam"),
|
||||
FREAKY_FORESTER(npc = FreakyForesterNPC(), skillId = Skills.WOODCUTTING),
|
||||
TREE_SPIRIT(npc = TreeSpiritRENPC(), skillId = Skills.WOODCUTTING),
|
||||
RIVER_TROLL(RiverTrollRENPC(), skillId = Skills.FISHING),
|
||||
ROCK_GOLEM(RockGolemRENPC(), skillId = Skills.MINING),
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
package content.global.ame.events.freakyforester
|
||||
|
||||
import core.api.*
|
||||
import org.rs09.consts.NPCs
|
||||
import org.rs09.consts.Scenery
|
||||
import core.game.interaction.IntType
|
||||
import core.game.interaction.InteractionListener
|
||||
import core.game.node.entity.Entity
|
||||
import core.game.system.task.Pulse
|
||||
import core.game.world.map.zone.ZoneBorders
|
||||
import core.game.world.map.zone.ZoneRestriction
|
||||
import org.rs09.consts.Items
|
||||
|
||||
class FreakListeners : InteractionListener, MapArea {
|
||||
|
||||
private val exitPortal = Scenery.PORTAL_8972
|
||||
private val freakNpc = NPCs.FREAKY_FORESTER_2458
|
||||
private val pheasants = intArrayOf(NPCs.PHEASANT_2459,NPCs.PHEASANT_2460,NPCs.PHEASANT_2461,NPCs.PHEASANT_2462)
|
||||
override fun defineListeners() {
|
||||
on(freakNpc,IntType.NPC,"talk-to"){player, node ->
|
||||
if (getAttribute(player, FreakUtils.freakTask, -1) == -1) FreakUtils.giveFreakTask(player)
|
||||
openDialogue(player, FreakyForesterDialogue(), node.asNpc())
|
||||
return@on true
|
||||
}
|
||||
|
||||
on(pheasants,IntType.NPC,"attack") { player, node ->
|
||||
if (getAttribute(player,FreakUtils.freakComplete, false)) {
|
||||
sendMessage(player,"You don't need to attack any more pheasants. You're allowed to leave.")
|
||||
} else if (inInventory(player, Items.RAW_PHEASANT_6178) || inInventory(player, Items.RAW_PHEASANT_6179) || getAttribute(player, FreakUtils.pheasantKilled, false)){
|
||||
sendMessage(player,"You don't need to attack any more pheasants.")
|
||||
} else {
|
||||
player.attack(node.asNpc())
|
||||
}
|
||||
return@on true
|
||||
}
|
||||
|
||||
on(exitPortal,IntType.SCENERY,"enter") { player, _ ->
|
||||
if (getAttribute(player,FreakUtils.freakComplete,false)) {
|
||||
FreakUtils.cleanup(player)
|
||||
submitWorldPulse(object : Pulse(2) {
|
||||
override fun pulse(): Boolean {
|
||||
FreakUtils.reward(player)
|
||||
return true
|
||||
}
|
||||
})
|
||||
return@on true
|
||||
} else sendMessage(player,"A supernatural force prevents you from leaving.")
|
||||
return@on true
|
||||
}
|
||||
}
|
||||
override fun defineAreaBorders(): Array<ZoneBorders> {
|
||||
return arrayOf(ZoneBorders(2587, 4758, 2616,4788))
|
||||
}
|
||||
|
||||
override fun getRestrictions(): Array<ZoneRestriction> {
|
||||
return arrayOf(ZoneRestriction.RANDOM_EVENTS, ZoneRestriction.CANNON, ZoneRestriction.FOLLOWERS)
|
||||
}
|
||||
|
||||
override fun areaEnter(entity: Entity) {
|
||||
entity.locks.lockTeleport(1000000)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
package content.global.ame.events.freakyforester
|
||||
|
||||
import core.api.*
|
||||
import org.rs09.consts.Items
|
||||
import org.rs09.consts.NPCs
|
||||
import core.game.node.entity.player.Player
|
||||
import core.game.world.map.Location
|
||||
import core.tools.RandomFunction
|
||||
|
||||
object FreakUtils{
|
||||
const val freakNpc = NPCs.FREAKY_FORESTER_2458
|
||||
const val freakPreviousLoc = "/save:freakyf:location"
|
||||
const val freakTask = "/save:freakyf:task"
|
||||
const val freakComplete = "/save:freakyf:complete"
|
||||
const val pheasantKilled = "freakyf:killed"
|
||||
fun giveFreakTask(player: Player) {
|
||||
when(RandomFunction.getRandom(4)) {
|
||||
0 -> setAttribute(player, freakTask, NPCs.PHEASANT_2459)
|
||||
1 -> setAttribute(player, freakTask, NPCs.PHEASANT_2460)
|
||||
2 -> setAttribute(player, freakTask, NPCs.PHEASANT_2461)
|
||||
3 -> setAttribute(player, freakTask, NPCs.PHEASANT_2462)
|
||||
else -> setAttribute(player, freakTask, NPCs.PHEASANT_2459)
|
||||
}
|
||||
player.dialogueInterpreter.open(FreakyForesterDialogue(), freakNpc)
|
||||
}
|
||||
|
||||
fun teleport(player: Player) {
|
||||
setAttribute(player, freakPreviousLoc, player.location)
|
||||
teleport(player, Location.create(2599, 4777 ,0))
|
||||
}
|
||||
|
||||
fun cleanup(player: Player) {
|
||||
player.locks.unlockTeleport()
|
||||
player.properties.teleportLocation = getAttribute(player,freakPreviousLoc,null)
|
||||
removeAttributes(player, freakPreviousLoc, freakTask, freakComplete, pheasantKilled)
|
||||
removeAll(player, Items.RAW_PHEASANT_6178)
|
||||
removeAll(player, Items.RAW_PHEASANT_6178, Container.BANK)
|
||||
removeAll(player, Items.RAW_PHEASANT_6179)
|
||||
removeAll(player, Items.RAW_PHEASANT_6179, Container.BANK)
|
||||
}
|
||||
|
||||
fun reward(player: Player){
|
||||
val hasHat = hasAnItem(player, Items.LEDERHOSEN_HAT_6182).container != null
|
||||
val hasTop = hasAnItem(player, Items.LEDERHOSEN_TOP_6180).container != null
|
||||
val hasShort = hasAnItem(player, Items.LEDERHOSEN_SHORTS_6181).container != null
|
||||
sendNPCDialogue(player, freakNpc, "You get a lederhosen item as a reward for your help, many thanks!")
|
||||
when{
|
||||
(!hasHat) -> addItemOrDrop(player, Items.LEDERHOSEN_HAT_6182, 1)
|
||||
(!hasTop) -> addItemOrDrop(player, Items.LEDERHOSEN_TOP_6180, 1)
|
||||
(!hasShort) -> addItemOrDrop(player, Items.LEDERHOSEN_SHORTS_6181, 1)
|
||||
else ->{
|
||||
sendNPCDialogue(player, freakNpc, "You get some money for your help, many thanks!")
|
||||
addItemOrDrop(player, Items.COINS_995, 500)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package content.global.ame.events.freakyforester
|
||||
|
||||
import core.api.*
|
||||
import core.game.dialogue.DialogueFile
|
||||
import core.game.dialogue.FacialExpression
|
||||
import core.tools.END_DIALOGUE
|
||||
import org.rs09.consts.Items
|
||||
import org.rs09.consts.NPCs
|
||||
|
||||
class FreakyForesterDialogue : DialogueFile(){
|
||||
|
||||
override fun handle(componentID: Int, buttonID: Int) {
|
||||
if (removeItem(player!!, Items.RAW_PHEASANT_6179) && !getAttribute(player!!, FreakUtils.freakComplete, false)) {
|
||||
npcl(FacialExpression.NEUTRAL, "That's not the right one.").also { stage = END_DIALOGUE }
|
||||
setAttribute(player!!, FreakUtils.pheasantKilled, false)
|
||||
} else if (removeItem(player!!, Items.RAW_PHEASANT_6178) || getAttribute(player!!, FreakUtils.freakComplete, false)) {
|
||||
npcl(FacialExpression.NEUTRAL, "Thanks, ${player!!.username}, you may leave the area now.").also { stage = END_DIALOGUE }
|
||||
sendChat(findNPC(FreakUtils.freakNpc)!!, "Thanks, ${player!!.username}, you may leave the area now.")
|
||||
setAttribute(player!!, FreakUtils.freakComplete, true)
|
||||
} else when (getAttribute(player!!, FreakUtils.freakTask, -1)) {
|
||||
NPCs.PHEASANT_2459 -> sendNPCDialogue(player!!, FreakUtils.freakNpc, "Hey there ${player!!.username}. Can you kill the one tailed pheasant please. Bring me the raw pheasant when you're done.").also { stage = END_DIALOGUE }
|
||||
NPCs.PHEASANT_2460 -> sendNPCDialogue(player!!, FreakUtils.freakNpc, "Hey there ${player!!.username}. Can you kill the two tailed pheasant please. Bring me the raw pheasant when you're done.").also { stage = END_DIALOGUE }
|
||||
NPCs.PHEASANT_2461 -> sendNPCDialogue(player!!, FreakUtils.freakNpc, "Hey there ${player!!.username}. Can you kill the three tailed pheasant please. Bring me the raw pheasant when you're done.").also { stage = END_DIALOGUE }
|
||||
NPCs.PHEASANT_2462 -> sendNPCDialogue(player!!, FreakUtils.freakNpc, "Hey there ${player!!.username}. Can you kill the four tailed pheasant please. Bring me the raw pheasant when you're done.").also { stage = END_DIALOGUE }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
package content.global.ame.events.freakyforester
|
||||
|
||||
import content.global.ame.RandomEventManager
|
||||
import content.global.ame.RandomEventNPC
|
||||
import core.api.*
|
||||
import org.rs09.consts.NPCs
|
||||
import core.api.utils.WeightBasedTable
|
||||
import core.game.node.entity.npc.NPC
|
||||
import core.game.system.task.Pulse
|
||||
import core.game.world.update.flag.context.Graphics
|
||||
import org.rs09.consts.Sounds
|
||||
|
||||
class FreakyForesterNPC(override var loot: WeightBasedTable? = null) : RandomEventNPC(NPCs.FREAKY_FORESTER_2458) {
|
||||
|
||||
override fun init() {
|
||||
super.init()
|
||||
lock(player, 8)
|
||||
submitWorldPulse(object : Pulse() {
|
||||
var counter = 0
|
||||
override fun pulse(): Boolean {
|
||||
when (counter++) {
|
||||
0 -> sendChat("Ah, ${player.username}, just the person I need!")
|
||||
4 -> {
|
||||
sendGraphics(Graphics(308, 100, 50), player.location)
|
||||
animate(player,714)
|
||||
playAudio(player, Sounds.TELEPORT_ALL_200)
|
||||
}
|
||||
7 -> {
|
||||
FreakUtils.teleport(player)
|
||||
FreakUtils.giveFreakTask(player)
|
||||
RandomEventManager.getInstance(player)!!.event?.terminate()
|
||||
openDialogue(player, FreakyForesterDialogue(), FreakUtils.freakNpc)
|
||||
resetAnimator(player)
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
override fun talkTo(npc: NPC) {
|
||||
player.dialogueInterpreter.open(FreakyForesterDialogue(),npc)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
package content.global.ame.events.freakyforester
|
||||
|
||||
import core.api.getAttribute
|
||||
import core.api.sendMessage
|
||||
import core.api.sendNPCDialogue
|
||||
import core.api.setAttribute
|
||||
import core.game.node.entity.Entity
|
||||
import core.game.node.entity.combat.BattleState
|
||||
import core.game.node.entity.npc.NPC
|
||||
import core.game.node.entity.npc.NPCBehavior
|
||||
import core.game.node.entity.player.Player
|
||||
import core.game.node.item.Item
|
||||
import org.rs09.consts.Items
|
||||
import org.rs09.consts.NPCs
|
||||
|
||||
class PheasantBehavior : NPCBehavior(NPCs.PHEASANT_2459, NPCs.PHEASANT_2460, NPCs.PHEASANT_2461, NPCs.PHEASANT_2462) {
|
||||
override fun onDropTableRolled(self: NPC, killer: Entity, drops: ArrayList<Item>) {
|
||||
val assignedPheasant = getAttribute(killer, FreakUtils.freakTask, -1)
|
||||
if (assignedPheasant == -1) return
|
||||
drops.removeLast()
|
||||
if (assignedPheasant == self.id) {
|
||||
drops.add(Item (Items.RAW_PHEASANT_6178))
|
||||
} else {
|
||||
drops.add(Item (Items.RAW_PHEASANT_6179))
|
||||
}
|
||||
setAttribute(killer, FreakUtils.pheasantKilled, true)
|
||||
}
|
||||
|
||||
override fun beforeDamageReceived(self: NPC, attacker: Entity, state: BattleState) {
|
||||
state.estimatedHit = 5
|
||||
state.secondaryHit = 0
|
||||
}
|
||||
|
||||
override fun getXpMultiplier(self: NPC, attacker: Entity): Double {
|
||||
return 0.0
|
||||
}
|
||||
}
|
||||
@@ -69,7 +69,7 @@ class ImplingBehavior : NPCBehavior (*Impling.getIds()) {
|
||||
}
|
||||
|
||||
//manually clear any rolled drops so any drops set by JSON are properly ignored.
|
||||
override fun onDropTableRolled (self: NPC, drops: ArrayList<Item>) {
|
||||
override fun onDropTableRolled (self: NPC, killer: Entity, drops: ArrayList<Item>) {
|
||||
drops.clear()
|
||||
}
|
||||
|
||||
|
||||
@@ -483,10 +483,13 @@ abstract class CombatSwingHandler(var type: CombatStyle?) {
|
||||
is Player -> {player = entity; attStyle = entity.properties.attackStyle.style}
|
||||
else -> return
|
||||
}
|
||||
if (victim is NPC) EXPERIENCE_MOD *= victim.behavior.getXpMultiplier(victim, player)
|
||||
if (state != null) {
|
||||
val hit = state.totalDamage
|
||||
if (entity is Player) {
|
||||
player.skills.addExperience(Skills.HITPOINTS, hit * 1.33, true)
|
||||
var experience = hit * 1.33
|
||||
if (victim is NPC) experience *= victim.behavior.getXpMultiplier(victim, player)
|
||||
player.skills.addExperience(Skills.HITPOINTS, experience, true)
|
||||
}
|
||||
|
||||
var skill = -1
|
||||
@@ -513,8 +516,10 @@ abstract class CombatSwingHandler(var type: CombatStyle?) {
|
||||
|
||||
WeaponInterface.STYLE_CAST -> skill = Skills.MAGIC
|
||||
WeaponInterface.STYLE_DEFENSIVE_CAST -> {
|
||||
player.skills.addExperience(Skills.MAGIC, hit * 1.33, true)
|
||||
player.skills.addExperience(Skills.DEFENCE, hit.toDouble(), true)
|
||||
var experience = hit.toDouble()
|
||||
if (victim is NPC) experience *= victim.behavior.getXpMultiplier(victim, player)
|
||||
player.skills.addExperience(Skills.MAGIC, experience * 1.33, true)
|
||||
player.skills.addExperience(Skills.DEFENCE, experience, true)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
@@ -99,9 +99,10 @@ open class NPCBehavior(vararg val ids: Int = intArrayOf()) : ContentInterface {
|
||||
/**
|
||||
* Called after this NPC's drop table is rolled, but before the items are actually dropped, so the list can be manipulated.
|
||||
* @param self the NPC instance this behavior belongs to
|
||||
* @param killer the killer of the npc
|
||||
* @param drops the generated list of drops for this roll of the table
|
||||
*/
|
||||
open fun onDropTableRolled(self: NPC, drops: ArrayList<Item>) {}
|
||||
open fun onDropTableRolled(self: NPC, killer: Entity, drops: ArrayList<Item>) {}
|
||||
|
||||
/**
|
||||
* Called by combat-related code to check if this NPC can be attacked by the `attacker` entity.
|
||||
@@ -139,4 +140,14 @@ open class NPCBehavior(vararg val ids: Int = intArrayOf()) : ContentInterface {
|
||||
open fun getClippingSupplier(self: NPC) : ClipMaskSupplier? {
|
||||
return StandardClipMaskSupplier
|
||||
}
|
||||
|
||||
/**
|
||||
* Modifies the combat experience gained from killing an entity
|
||||
* @param self the NPC instance this behavior belongs to
|
||||
* @param attacker entity attacking the npc
|
||||
* @return multiplier for final xp gain
|
||||
*/
|
||||
open fun getXpMultiplier(self: NPC, attacker: Entity) : Double {
|
||||
return 1.0
|
||||
}
|
||||
}
|
||||
|
||||
@@ -75,7 +75,7 @@ public final class NPCDropTables {
|
||||
public void drop(NPC npc, Entity looter) {
|
||||
Player p = looter instanceof Player ? (Player) looter : null;
|
||||
ArrayList<Item> drops = table.roll(looter);
|
||||
npc.behavior.onDropTableRolled(npc, drops);
|
||||
npc.behavior.onDropTableRolled(npc, looter, drops);
|
||||
drops.forEach(item -> createDrop(item,p,npc,npc.getDropLocation()));
|
||||
}
|
||||
|
||||
|
||||
@@ -551,6 +551,11 @@ class MiscCommandSet : CommandSet(Privilege.ADMIN){
|
||||
content.global.ame.RandomEventManager.getInstance(player)!!.event!!.init()
|
||||
}
|
||||
|
||||
define("freak", Privilege.ADMIN){ player, _ ->
|
||||
content.global.ame.RandomEventManager.getInstance(player)!!.event = RandomEvents.FREAKY_FORESTER.npc.create(player)
|
||||
content.global.ame.RandomEventManager.getInstance(player)!!.event!!.init()
|
||||
}
|
||||
|
||||
define("revent", Privilege.ADMIN){ player, _ ->
|
||||
println(player.pulseManager.current)
|
||||
content.global.ame.RandomEventManager.getInstance(player)!!.fireEvent()
|
||||
|
||||
Reference in New Issue
Block a user