uhhh go brrr?

This commit is contained in:
Ceikry
2021-03-11 20:42:32 -06:00
parent 89d51b788b
commit 76c7b16108
2757 changed files with 0 additions and 0 deletions
@@ -1,47 +0,0 @@
package core
import core.game.world.map.Location
import java.io.File
class JSONUtils {
companion object {
/**
* Parses a location from the format "x,y,z"
* @author Ceikry
* @param locString The string to parse
* @return Location
*/
@JvmStatic
fun parseLocation(locString: String): Location {
val locTokens = locString.split(",").map { it.toInt() }
return Location(locTokens[0], locTokens[1], locTokens[2])
}
/**
* Parses a path string
* @author Ceikry
* @param pathString The string to parse
* @return a String with the proper file separators for the current OS.
*/
@JvmStatic
fun parsePath(pathString: String): String {
var pathTokens: List<String>? = null
if(pathString.contains("/"))
pathTokens = pathString.split("/")
else if(pathString.contains("\\"))
pathTokens = pathString.split("\\")
pathTokens ?: return pathString //return the initial pathString if path does not contain file separators.
var pathProduct = ""
for(token in pathTokens){
if(token != "")
pathProduct += "$token${File.separator}"
}
return pathProduct
}
}
}
-142
View File
@@ -1,142 +0,0 @@
package core
import core.game.system.*
import core.game.system.config.ServerConfigParser
import core.game.system.mysql.SQLManager
import core.game.world.GameWorld
import core.game.world.repository.Repository
import core.gui.ConsoleFrame
import core.net.NioReactor
import core.net.amsc.WorldCommunicator
import core.tools.TimeStamp
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
import core.game.ge.GEAutoStock
import kotlinx.coroutines.delay
import java.io.File
import java.net.BindException
import java.util.*
import kotlin.system.exitProcess
/**
* The main class, for those that are unable to read the class' name.
* @author Emperor
* @author Vexia
* @author Ceikry
*/
object Server {
/**
* The time stamp of when the server started running.
*/
@JvmField
var startTime: Long = 0
var lastHeartbeat = System.currentTimeMillis()
var running = false
/**
* The NIO reactor.
*/
var reactor: NioReactor? = null
/**
* The main method, in this method we load background utilities such as
* cache and our world, then end with starting networking.
* @param args The arguments cast on runtime.
* @throws Throwable When an exception occurs.
*/
@Throws(Throwable::class)
@JvmStatic
fun main(args: Array<String>) {
if (args.isNotEmpty()) {
SystemLogger.logInfo("Using config file: ${args[0]}")
ServerConfigParser(args[0])
} else {
SystemLogger.logInfo("Using config file: ${"worldprops" + File.separator + "default.json"}")
ServerConfigParser("worldprops" + File.separator + "default.json")
}
if (GameWorld.settings?.isGui == true) {
try {
ConsoleFrame.getInstance().init()
} catch (e: Exception) {
SystemLogger.logWarn("X11 server missing - launching server with no GUI!")
}
}
startTime = System.currentTimeMillis()
val t = TimeStamp()
GameWorld.prompt(true)
SQLManager.init()
Runtime.getRuntime().addShutdownHook(ServerConstants.SHUTDOWN_HOOK)
SystemLogger.logInfo("Starting networking...")
try {
NioReactor.configure(43594 + GameWorld.settings?.worldId!!).start()
} catch (e: BindException) {
SystemLogger.logErr("Port " + (43594 + GameWorld.settings?.worldId!!) + " is already in use!")
throw e
}
WorldCommunicator.connect()
SystemLogger.logInfo(GameWorld.settings?.name + " flags " + GameWorld.settings?.toString())
SystemLogger.logInfo(GameWorld.settings?.name + " started in " + t.duration(false, "") + " milliseconds.")
GEAutoStock.autostock()
val scanner = Scanner(System.`in`)
running = true
GlobalScope.launch {
while(scanner.hasNextLine()){
val command = scanner.nextLine()
when(command){
"stop" -> SystemManager.flag(SystemState.TERMINATED)
"players" -> System.out.println("Players online: " + (Repository.LOGGED_IN_PLAYERS.size))
"update" -> SystemManager.flag(SystemState.UPDATING)
"help","commands" -> printCommands()
"restartworker" -> SystemManager.flag(SystemState.ACTIVE)
}
}
}
GlobalScope.launch {
delay(20000)
while(running){
if(System.currentTimeMillis() - lastHeartbeat > 1800){
running = false
exitProcess(0)
}
delay(625)
}
}
}
@JvmStatic
fun heartbeat() {
lastHeartbeat = System.currentTimeMillis()
}
fun printCommands(){
println("stop - stop the server (saves all accounts and such)")
println("players - show online player count")
println("update - initiate an update with a countdown visible to players")
println("help, commands - show this")
println("restartworker - Reboots the major update worker in case of a travesty.")
}
fun autoReconnect() {
/*SystemLogger.log("Attempting autoreconnect of server")
WorldCommunicator.connect()*/
}
/**
* Gets the startTime.
* @return the startTime
*/
fun getStartTime(): Long {
return startTime
}
/**
* Sets the bastartTime.ZZ
* @param startTime the startTime to set.
*/
fun setStartTime(startTime: Long) {
Server.startTime = startTime
}
}
@@ -1,217 +0,0 @@
package core
import core.game.system.SystemShutdownHook
import core.game.system.mysql.SQLManager
import core.game.world.map.Location
import core.tools.mysql.Database
import core.tools.secondsToTicks
import org.json.simple.JSONObject
import java.io.File
import java.math.BigInteger
/**
* A class holding various variables for the server.
* @author Ceikry
*/
class ServerConstants {
companion object {
@JvmField
var SHUTDOWN_HOOK: Thread = Thread(SystemShutdownHook())
@JvmField
var DATA_PATH: String? = null
//path to the cache
@JvmField
var CACHE_PATH: String? = null
//path for the server store (obsolete, but kept for the sake of system sanity.)
@JvmField
var STORE_PATH: String? = null
//path for player saves
@JvmField
var PLAYER_SAVE_PATH: String? = null
@JvmField
var PLAYER_ATTRIBUTE_PATH = "ish";
//path to the various config files, such as npc_spawns.json
var CONFIG_PATH: String? = null
@JvmField
var GRAND_EXCHANGE_DATA_PATH: String? = null
@JvmField
var RDT_DATA_PATH: String? = null
@JvmField
var OBJECT_PARSER_PATH: String? = null
@JvmField
var SCRIPTS_PATH: String? = null
@JvmField
var DIALOGUE_SCRIPTS_PATH: String? = null
@JvmField
var LOGS_PATH: String? = null
@JvmField
var BOT_DATA_PATH: String? = null
//the max number of players.
@JvmField
var MAX_PLAYERS = 0
//the max number of NPCs
@JvmField
var MAX_NPCS = 0
//the location where new players are placed on login.
@JvmField
var START_LOCATION: Location? = null
//Location for all home teleports/respawn location
@JvmField
var HOME_LOCATION: Location? = null
//the name for the database
@JvmField
var DATABASE_NAME: String? = null
//username for the database
@JvmField
var DATABASE_USER: String? = null
//password for the database
@JvmField
var DATABASE_PASS: String? = null
//address for the database
@JvmField
var DATABASE_ADDRESS: String? = null
@JvmField
var DATABASE_PORT: String? = null
@JvmField
var WRITE_LOGS: Boolean = false
@JvmField
var BANK_SIZE: Int = 496
@JvmField
var GE_AUTOSAVE_FREQUENCY = secondsToTicks(3600) //1 hour
@JvmField
var GE_AUTOSTOCK_ENABLED = false
//location names for the ::to command.
val TELEPORT_DESTINATIONS = arrayOf(
arrayOf(Location.create(2974, 4383, 2), "corp", "corporal", "corporeal"),
arrayOf(Location.create(2659, 2649, 0), "pc", "pest control", "pest"),
arrayOf(Location.create(3293, 3184, 0), "al kharid", "alkharid", "kharid"),
arrayOf(Location.create(3222, 3217, 0), "lumbridge", "lumby"),
arrayOf(Location.create(3110, 3168, 0), "wizard tower", "wizards tower", "tower", "wizards"),
arrayOf(Location.create(3083, 3249, 0), "draynor", "draynor village"),
arrayOf(Location.create(3019, 3244, 0), "port sarim", "sarim"),
arrayOf(Location.create(2956, 3209, 0), "rimmington"),
arrayOf(Location.create(2965, 3380, 0), "fally", "falador"),
arrayOf(Location.create(2895, 3436, 0), "taverley"),
arrayOf(Location.create(3080, 3423, 0), "barbarian village", "barb"),
arrayOf(Location.create(3213, 3428, 0), "varrock"),
arrayOf(Location.create(3164, 3485, 0), "grand exchange", "ge"),
arrayOf(Location.create(2917, 3175, 0), "karamja"),
arrayOf(Location.create(2450, 5165, 0), "tzhaar"),
arrayOf(Location.create(2795, 3177, 0), "brimhaven"),
arrayOf(Location.create(2849, 2961, 0), "shilo village", "shilo"),
arrayOf(Location.create(2605, 3093, 0), "yanille"),
arrayOf(Location.create(2663, 3305, 0), "ardougne", "ardy"),
arrayOf(Location.create(2450, 3422, 0), "gnome stronghold", "gnome"),
arrayOf(Location.create(2730, 3485, 0), "camelot", "cammy", "seers"),
arrayOf(Location.create(2805, 3435, 0), "catherby"),
arrayOf(Location.create(2659, 3657, 0), "rellekka"),
arrayOf(Location.create(2890, 3676, 0), "trollheim"),
arrayOf(Location.create(2914, 3746, 0), "godwars", "gwd", "god wars"),
arrayOf(Location.create(3180, 3684, 0), "bounty hunter", "bh"),
arrayOf(Location.create(3272, 3687, 0), "clan wars", "clw"),
arrayOf(Location.create(3090, 3957, 0), "mage arena", "mage", "magearena", "arena"),
arrayOf(Location.create(3069, 10257, 0), "king black dragon", "kbd"),
arrayOf(Location.create(3359, 3416, 0), "digsite"),
arrayOf(Location.create(3488, 3489, 0), "canifis"),
arrayOf(Location.create(3428, 3526, 0), "slayer tower", "slayer"),
arrayOf(Location.create(3502, 9483, 2), "kalphite queen", "kq", "kalphite hive", "kalphite"),
arrayOf(Location.create(3233, 2913, 0), "pyramid"),
arrayOf(Location.create(3419, 2917, 0), "nardah"),
arrayOf(Location.create(3482, 3090, 0), "uzer"),
arrayOf(Location.create(3358, 2970, 0), "pollnivneach", "poln"),
arrayOf(Location.create(3305, 2788, 0), "sophanem"),
arrayOf(Location.create(2898, 3544, 0), "burthorpe", "burthorp"),
arrayOf(Location.create(3088, 3491, 0), "edge", "edgeville"),
arrayOf(Location.create(3169, 3034, 0), "bedabin"),
arrayOf(Location.create(3565, 3289, 0), "barrows"),
arrayOf(Location.create(3016, 3513, 0), "bkf", "black knights fortress"),
arrayOf(Location.create(3052, 3481, 0), "monastery")
)
@JvmField
var DATABASE: Database? = null
//if SQL is enabled
@JvmField
var MYSQL = true
//the server name
@JvmField
var SERVER_NAME: String = ""
//The RSA_KEY for the server.
@JvmField
var EXPONENT = BigInteger("52317200263721308660411803146360972546561037484450290559823448967617618536819222494429186211525706853703641369936136465589036631055945454547936148730495933263344792588795811788941129493188907621550836988152620502378278134421731002382361670176785306598134280732756356458964850508114958769985438054979422820241")
//The MODULUS for the server.
@JvmField
var MODULUS = BigInteger("96982303379631821170939875058071478695026608406924780574168393250855797534862289546229721580153879336741968220328805101128831071152160922518190059946555203865621183480223212969502122536662721687753974815205744569357388338433981424032996046420057284324856368815997832596174397728134370577184183004453899764051")
/**
* Parses a JSONObject and retrieves the values for all settings in this file.
* @author Ceikry
* @param data : The JSONObject to parse.
*/
fun parse(data: JSONObject) {
MAX_PLAYERS = data["max_players"].toString().toInt()
MAX_NPCS = data["max_npcs"].toString().toInt()
START_LOCATION = JSONUtils.parseLocation(data["new_player_location"].toString())
HOME_LOCATION = JSONUtils.parseLocation(data["home_location"].toString())
DATA_PATH = JSONUtils.parsePath(data["data_path"].toString())
CACHE_PATH = JSONUtils.parsePath(data["cache_path"].toString())
STORE_PATH = JSONUtils.parsePath(data["store_path"].toString())
PLAYER_SAVE_PATH = JSONUtils.parsePath(data["save_path"].toString())
CONFIG_PATH = JSONUtils.parsePath(data["configs_path"].toString())
PLAYER_ATTRIBUTE_PATH = PLAYER_SAVE_PATH + "attributes" + File.separator
GRAND_EXCHANGE_DATA_PATH = JSONUtils.parsePath(data["grand_exchange_data_path"].toString())
BOT_DATA_PATH = JSONUtils.parsePath(data["bot_data_path"].toString())
RDT_DATA_PATH = JSONUtils.parsePath(data["rare_drop_table_path"].toString())
OBJECT_PARSER_PATH = JSONUtils.parsePath(data["object_parser_path"].toString())
SCRIPTS_PATH = JSONUtils.parsePath(data["scripts_path"].toString())
DIALOGUE_SCRIPTS_PATH = JSONUtils.parsePath(data["dialogue_scripts_path"].toString())
if(data.containsKey("logs_path")){
LOGS_PATH = data["logs_path"].toString()
}
if(data.containsKey("writeLogs")){
WRITE_LOGS = data["writeLogs"] as Boolean
}
DATABASE_NAME = data["database_name"].toString()
DATABASE_USER = data["database_username"].toString()
DATABASE_PASS = data["database_password"].toString()
DATABASE_ADDRESS = data["database_address"].toString()
DATABASE_PORT = data["database_port"].toString()
DATABASE = Database(DATABASE_ADDRESS, DATABASE_NAME, DATABASE_USER, DATABASE_PASS)
}
}
}
@@ -1,5 +0,0 @@
package core.game
class Varbit(var value: Int, val offset: Int){
}
@@ -1,70 +0,0 @@
package core.game
import core.game.node.entity.player.Player
import core.game.system.SystemLogger
/**
* A class that represents Varps and aids in modifying/calculating them
* @author Ceikry
*/
class Varp(val index: Int) {
val varbits = ArrayList<Varbit>()
var save = false
fun setVarbit(offset: Int, value: Int): Varp{
for(vb in varbits){
if (vb.offset == offset){
varbits.remove(vb)
break
}
}
varbits.add(Varbit(value,offset))
return this
}
fun getValue(): Int{
var config = 0
for(varbit in varbits){
config = config or (varbit.value shl varbit.offset)
}
return config
}
fun getVarbit(offset: Int): Varbit?{
for(varbit in varbits){
if(varbit.offset == offset) return varbit
}
return null
}
fun getVarbitValue(offset: Int): Int{
return getVarbit(offset)?.value ?: 0
}
fun send(player: Player){
player.packetDispatch.sendVarp(this)
}
fun clear(): Varp{
varbits.clear()
return this
}
fun clearBitRange(first : Int, last : Int){
for(varbit in varbits){
if(varbit.offset in first..last){
varbit.value = 0
}
}
}
fun getBitRangeValue(first: Int, last: Int): Int{
var product = 0
for(varbit in varbits){
if(varbit.offset in first..last){
product = product or (varbit.value shl varbit.offset)
}
}
return product
}
}
@@ -1,91 +0,0 @@
package core.game
import core.cache.def.impl.VarbitDefinition
import core.game.node.entity.player.Player
import org.json.simple.JSONArray
import org.json.simple.JSONObject
/**
* Manages the collection of a player's varps.
* Also handles saving and loading of saved varps.
* @author Ceikry
*/
class VarpManager(val player: Player) {
val varps = Array(3500) { Varp(it) }
fun get(index: Int): Varp{
return varps[index]
}
fun send(index: Int){
player.packetDispatch.sendVarp(get(index))
}
fun set(index: Int, value: Int){
get(index).varbits.clear()
get(index).varbits.add(Varbit(value,0))
get(index).send(player)
}
fun setVarbit(def: VarbitDefinition, value: Int){
get(def.configId).setVarbit(def.bitShift,value).send(player)
}
fun flagSave(index: Int){
get(index).save = true
}
fun unflagSave(index: Int){
get(index).save = false
}
fun sendAllVarps(){
for(varp in varps){
if(varp.getValue() != 0){
player.packetDispatch.sendVarp(varp)
}
}
}
fun getSavedVarps(): ArrayList<Varp>{
val list = ArrayList<Varp>()
for(varp in varps){
if(varp.save) list.add(varp)
}
return list
}
fun save(root: JSONObject){
val varps = JSONArray()
for(varp in getSavedVarps()){
val varpobj = JSONObject()
varpobj.put("index",varp.index.toString())
val bitArray = JSONArray()
for(varbit in varp.varbits){
val varbitobj = JSONObject()
varbitobj.put("offset",varbit.offset.toString())
varbitobj.put("value",varbit.value.toString())
bitArray.add(varbitobj)
}
varpobj.put("bitArray",bitArray)
varps.add(varpobj)
}
root.put("varps",varps)
}
fun parse(data: JSONArray){
for(varpobj in data){
val vobj = varpobj as JSONObject
val index = vobj["index"].toString().toInt()
val varp = get(index)
val bits = vobj["bitArray"] as JSONArray
for(vbit in bits){
val varbit = vbit as JSONObject
val offset = varbit["offset"].toString().toInt()
val value = varbit["value"].toString().toInt()
varp.setVarbit(offset,value)
varp.save = true
}
}
}
}
@@ -1,5 +0,0 @@
package core.game.camerautils
object CameraUtils {
}
@@ -1,33 +0,0 @@
package core.game.camerautils
import core.game.node.entity.player.Player
import core.game.system.SystemLogger
import core.net.packet.PacketRepository
import core.net.packet.context.CameraContext
import core.net.packet.out.CameraViewPacket
class PlayerCamera(val player: Player?) {
var ctx: CameraContext? = null
fun setPosition(x: Int, y: Int, height: Int){
player ?: return
ctx = CameraContext(player,CameraContext.CameraType.SET,x,y,height,0,0)
PacketRepository.send(CameraViewPacket::class.java,ctx)
}
fun rotateTo(x: Int, y: Int, height: Int, speed: Int){
player ?: return
ctx = CameraContext(player,CameraContext.CameraType.ROTATION,x,y,height,speed,1)
PacketRepository.send(CameraViewPacket::class.java,ctx)
}
fun rotateBy(diffX: Int, diffY: Int, diffHeight: Int, speed: Int){
player ?: return
ctx ?: return
ctx = CameraContext(player,CameraContext.CameraType.ROTATION, ctx!!.x + diffX, ctx!!.y + diffY, ctx!!.height + diffHeight,speed,1)
PacketRepository.send(CameraViewPacket::class.java,ctx)
}
fun panTo(x: Int, y: Int, height: Int, speed: Int){
player ?: return
ctx = CameraContext(player,CameraContext.CameraType.POSITION,x,y,height,speed,1)
PacketRepository.send(CameraViewPacket::class.java,ctx)
}
}
@@ -1,73 +0,0 @@
package core.game.content.activity.allfiredup
import core.game.node.entity.player.Player
import core.game.system.SystemLogger
import core.game.world.map.Location
/**
* Various data for beacons, such as varp and offset, required FM level, etc
* @author Ceikry
*/
enum class AFUBeacon(val title: String, val fmLevel: Int, val varpId: Int, val offset: Int, val location: Location, val experience: Double, val keeper: Int = 0) {
RIVER_SALVE("",43,1283,0,Location.create(3396, 3464, 0),216.2,8065),
RAG_AND_BONE("",43,1283,3,Location.create(3343, 3510, 0),235.8,8066),
JOLLY_BOAR("",48,1283,6,Location.create(3278, 3525, 0), 193.8,8067),
NORTH_VARROCK_CASTLE("",53,1283,9,Location.create(3236, 3527, 0),178.5,8068),
GRAND_EXCHANGE("",59,1283,12,Location.create(3170, 3536, 0),194.3,8069),
EDGEVILLE("",62,1283,15,Location.create(3087, 3516, 0),86.7,8070),
MONASTERY("",68,1283,18,Location.create(3034, 3518, 0),224.4,8071),
GOBLIN_VILLAGE("",72,1283,21,Location.create(2968, 3516, 0),194.8,8072),
BURTHORPE("",76,1283,24,Location.create(2940, 3565, 0),195.3,8073),
DEATH_PLATEAU("",79,1288,0,Location.create(2944, 3622, 0),249.9,8074),
TROLLHEIM("",83,1288,3,Location.create(2939, 3680, 0),201.0,8075),
GWD("",87,1288,6,Location.create(2937, 3773, 0),255.0,8076),
TEMPLE("",89,1288,9,Location.create(2946, 3836, 0),198.9),
PLATEAU("",92,1288,12,Location.create(2964, 3931, 0),147.9);
companion object {
fun forLocation(location: Location): AFUBeacon {
for (beacon in values()) {
if (beacon.location.equals(location)) return beacon
}
return RIVER_SALVE.also { SystemLogger.logWarn("Unhandled Beacon Location ${location.toString()}") }
}
fun resetAllBeacons(player: Player){
for(beacon in values()){
player.varpManager.get(beacon.varpId).setVarbit(beacon.offset,0).send(player)
}
}
}
fun light(player: Player){
player.varpManager.get(varpId).setVarbit(offset,2).send(player)
}
fun diminish(player: Player){
player.varpManager.get(varpId).setVarbit(offset,3).send(player)
}
fun extinguish(player: Player){
player.varpManager.get(varpId).setVarbit(offset,0).send(player)
}
fun lightGnomish(player: Player){
player.varpManager.get(varpId).setVarbit(offset,4).send(player)
}
fun fillWithLogs(player: Player){
player.varpManager.get(varpId).setVarbit(offset,1).send(player)
}
fun getState(player: Player): BeaconState{
return BeaconState.values()[player.varpManager.get(varpId).getVarbit(offset)?.value ?: 0]
}
}
enum class BeaconState{
EMPTY,
FILLED,
LIT,
DYING,
WARNING
}
@@ -1,229 +0,0 @@
package core.game.content.activity.allfiredup
import core.cache.def.impl.ObjectDefinition
import core.game.interaction.OptionHandler
import core.game.node.Node
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.GameWorld
import core.game.world.update.flag.context.Animation
import core.plugin.Initializable
import core.plugin.Plugin
import core.tools.Items
import core.game.content.dialogue.FacialExpression
import core.game.node.entity.skill.Skills
private val VALID_LOGS = arrayOf(Items.LOGS_1511,Items.OAK_LOGS_1521,Items.WILLOW_LOGS_1519,Items.MAPLE_LOGS_1517,Items.YEW_LOGS_1515,Items.MAGIC_LOGS_1513)
private val FILL_ANIM = Animation(9136)
private val LIGHT_ANIM = Animation(7307)
/**
* Handles interactions for beacons
* @author Ceikry
*/
@Initializable
class AFUBeaconHandler : OptionHandler(){
override fun newInstance(arg: Any?): Plugin<Any> {
for(i in 38448..38461)
ObjectDefinition.forId(i).childrenIds.forEach {
ObjectDefinition.forId(it).handlers["option:add-logs"] = this
ObjectDefinition.forId(it).handlers["option:light"] = this
}
return this
}
override fun handle(player: Player?, node: Node?, option: String?): Boolean {
player ?: return false
node ?: return false
val beacon = AFUBeacon.forLocation(node.location)
val questComplete = player.questRepository.isComplete("All Fired Up")
val questStage = player.questRepository.getStage("All Fired Up")
if ((beacon != AFUBeacon.RIVER_SALVE && beacon != AFUBeacon.RAG_AND_BONE && !questComplete)
|| (beacon == AFUBeacon.RIVER_SALVE && questStage < 20 && !questComplete)
|| (beacon == AFUBeacon.RAG_AND_BONE && questStage < 50 && !questComplete)) {
player.dialogueInterpreter.sendDialogues(player, FacialExpression.THINKING, "I probably shouldn't mess with this.")
return true
}
player.debug(beacon.getState(player).name)
when (beacon.getState(player)) {
BeaconState.EMPTY -> fillBeacon(player, beacon, questComplete)
BeaconState.DYING -> restoreBeacon(player, beacon, questComplete)
BeaconState.FILLED -> lightBeacon(player, beacon, questComplete)
BeaconState.LIT, BeaconState.WARNING -> {
player.debug("INVALID BEACON STATE")
}
}
return true
}
fun fillBeacon(player: Player, beacon: AFUBeacon, questComplete: Boolean){
when(beacon){
AFUBeacon.MONASTERY -> {
if(player.skills.getLevel(Skills.PRAYER) < 31){
player.dialogueInterpreter.sendDialogues(NPC(beacon.keeper).getShownNPC(player),FacialExpression.ANGRY,"You must join the monastery to light this beacon!")
return
}
}
AFUBeacon.GWD -> {
if(!AFURepairClimbHandler.isRepaired(player,beacon)){
player.dialogueInterpreter.sendDialogue("You must repair the windbreak before you","can light this beacon.")
return
}
}
AFUBeacon.GOBLIN_VILLAGE -> {
if(!player.questRepository.isComplete("Lost Tribe")){
player.dialogueInterpreter.sendDialogues(NPC(beacon.keeper).getShownNPC(player),FacialExpression.THINKING,"We no trust you outsider. You no light our beacon.","(Complete Lost Tribe to use this beacon.)")
return
}
}
}
if(player.skills.getLevel(Skills.FIREMAKING) < beacon.fmLevel){
player.dialogueInterpreter.sendDialogue("You need ${beacon.fmLevel} Firemaking to light this beacon.")
return
}
val logs = getLogs(player,20)
if (logs.id != 0 && player.inventory.remove(logs)) {
player.lock()
var session: AFUSession? = null
if(questComplete){
session = player.getAttribute("afu-session", null)
if(session == null) {
session = AFUSession(player)
session.init()
}
}
GameWorld.Pulser.submit(object : Pulse() {
var counter = 0
override fun pulse(): Boolean {
when (counter++) {
0 -> player.animator.animate(FILL_ANIM)
1 -> {
beacon.fillWithLogs(player)
if(questComplete){
session?.setLogs(beacon.ordinal,logs)
}
player.varpManager.flagSave(beacon.varpId);
}
2 -> player.unlock().also {player.animator.animate(Animation.RESET); return true }
}
return false
}
})
} else {
player.dialogueInterpreter.sendDialogue("You need some logs to do this.")
}
}
fun lightBeacon(player: Player,beacon: AFUBeacon, questComplete: Boolean){
var session: AFUSession? = null
if(questComplete){
session = player.getAttribute("afu-session",null)
if(session == null) return
}
if(player.inventory.contains(Items.TINDERBOX_590,1)){
player.lock()
GameWorld.Pulser.submit(object: Pulse(){
var counter = 0
override fun pulse(): Boolean {
when(counter++){
0 -> player.animator.animate(LIGHT_ANIM)
1 -> {
beacon.light(player)
if(questComplete){
session?.startTimer(beacon.ordinal)
if(session?.getLitBeacons() == 6 && !player.hasFireRing()){
player.sendMessage("Congratulations on lighting 6 beacons at once! King Roald has something for you.")
player.setAttribute("/save:afu-mini:ring",true)
}
if(session?.getLitBeacons() == 10 && !player.hasFlameGloves()){
player.sendMessage("Congratulations on lighting 10 beacons at once! King Roald has something for you.")
player.setAttribute("/save:afu-mini:gloves",true)
}
if(session?.getLitBeacons() == 14 && !player.hasInfernoAdze()){
player.sendMessage("Congratulations on lighting all 14 beacons! King Roald has something special for you.")
player.setAttribute("/save:afu-mini:adze",true)
}
var experience = beacon.experience
experience += session?.getBonusExperience() ?: 0.0
player.skills.addExperience(Skills.FIREMAKING,experience)
} else {
player.questRepository.getQuest("All Fired Up").setStage(player, player.questRepository.getStage("All Fired Up") + 10)
}
}
2 -> player.unlock().also { return true }
}
return false
}
})
} else {
player.dialogueInterpreter.sendDialogue("You need a tinderbox to light this.")
}
}
fun restoreBeacon(player: Player,beacon: AFUBeacon, questComplete: Boolean){
var session: AFUSession? = null
if(questComplete){
session = player.getAttribute("afu-session",null)
if(session == null) return
}
val logs = getLogs(player, 5)
if (logs.id != 0 && player.inventory.remove(logs)) {
player.lock()
GameWorld.Pulser.submit(object: Pulse(){
var counter = 0
override fun pulse(): Boolean {
when(counter++){
0 -> player.animator.animate(FILL_ANIM)
1 -> beacon.light(player).also {
if(questComplete){
session?.refreshTimer(beacon,logs.id)
} else {
player.questRepository.getQuest("All Fired Up").setStage(player, 80)
}
}
2 -> player.unlock().also { return true }
}
return false
}
})
} else {
player.dialogueInterpreter.sendDialogue("You need some logs to do this.")
}
}
fun getLogs(player: Player, amount: Int): Item{
var logId = 0
for (log in VALID_LOGS) if (player.inventory.getAmount(log) >= amount) {logId = log; break}
return Item(logId,amount)
}
fun Player.hasFireRing(): Boolean{
return inventory.containsItem(Item(Items.RING_OF_FIRE_13659)) || bank.containsItem(Item(Items.RING_OF_FIRE_13659)) || equipment.containsItem(Item(Items.RING_OF_FIRE_13659))
}
fun Player.hasFlameGloves(): Boolean{
return inventory.containsItem(Item(Items.FLAME_GLOVES_13660)) || bank.containsItem(Item(Items.FLAME_GLOVES_13660)) || equipment.containsItem(Item(Items.FLAME_GLOVES_13660))
}
fun Player.hasInfernoAdze(): Boolean{
return inventory.containsItem(Item(Items.INFERNO_ADZE_13661)) || bank.containsItem(Item(Items.INFERNO_ADZE_13661)) || equipment.containsItem(Item(Items.INFERNO_ADZE_13661))
}
}
@@ -1,145 +0,0 @@
package core.game.content.activity.allfiredup
import core.cache.def.impl.ObjectDefinition
import core.game.interaction.OptionHandler
import core.game.node.Node
import core.game.node.entity.impl.ForceMovement
import core.game.node.entity.player.Player
import core.game.node.item.Item
import core.game.world.map.Direction
import core.game.world.map.Location
import core.game.world.update.flag.context.Animation
import core.plugin.Initializable
import core.plugin.Plugin
import core.tools.Items
import core.game.node.entity.skill.Skills
import core.game.node.entity.skill.construction.NailType
import java.util.*
/**
* Handles repairing and climbing of the 3 beacon shortcuts needed to access them
* @author Ceikry
*/
@Initializable
class AFURepairClimbHandler : OptionHandler() {
override fun newInstance(arg: Any?): Plugin<Any> {
ObjectDefinition.forId(38480).handlers["option:repair"] = this
ObjectDefinition.forId(38470).handlers["option:repair"] = this
ObjectDefinition.forId(38494).handlers["option:repair"] = this
ObjectDefinition.forId(38469).handlers["option:climb"] = this
ObjectDefinition.forId(38471).handlers["option:climb"] = this
ObjectDefinition.forId(38486).handlers["option:climb"] = this
ObjectDefinition.forId(38481).handlers["option:climb"] = this
ObjectDefinition.forId(38469).handlers["option:climb"] = this
return this
}
override fun handle(player: Player?, node: Node?, option: String?): Boolean {
player ?: return false
node ?: return false
var rco: RepairClimbObject = RepairClimbObject.GWD
for(ent in RepairClimbObject.values()) if(ent.destinationDown?.withinDistance(player.location,2) == true || ent.destinationUp?.withinDistance(player.location,2) == true) rco = ent
if(option.equals("repair")) repair(player,rco) else climb(player,rco,node.location)
return true
}
private fun repair(player: Player,rco: RepairClimbObject){
val skill = rco.levelRequirement?.first ?: 0
val level = rco.levelRequirement?.second ?: 0
if(player.skills.getLevel(skill) < level){
player.dialogueInterpreter.sendDialogue("You need level $level ${Skills.SKILL_NAME[skill]} for this.")
return
}
var requiresNeedle = false
val requiredItems = when(rco){
RepairClimbObject.DEATH_PLATEAU -> {
arrayOf(Item(Items.PLANK_960,2))
}
RepairClimbObject.BURTHORPE -> {
arrayOf(Item(Items.IRON_BAR_2351,2))
}
RepairClimbObject.GWD -> {
requiresNeedle = true
arrayOf(Item(Items.JUTE_FIBRE_5931,3))
}
RepairClimbObject.TEMPLE -> {
arrayOf(Item(Items.IRON_BAR_2351,2))
}
}
if(requiresNeedle){
if(player.inventory.containsItem(Item(Items.NEEDLE_1733)) && player.inventory.containItems(*requiredItems.map { it.id }.toIntArray())) {
player.inventory.remove(*requiredItems)
if (Random().nextBoolean()) player.inventory.remove(Item(Items.NEEDLE_1733))
} else {
player.dialogueInterpreter.sendDialogue("You need a needle and ${requiredItems.map { "${it.amount} ${it.name.toLowerCase()}s" }.toString().replace("[","").replace("]","")} for this.")
return
}
} else {
if(player.inventory.containsItem(Item(Items.HAMMER_2347)) && player.inventory.containItems(*requiredItems.map { it.id }.toIntArray())) {
val nails = NailType.get(player,4)
if(nails == null && rco == RepairClimbObject.DEATH_PLATEAU){
player.dialogueInterpreter.sendDialogue("You need 4 nails for this.")
return
} else if (rco == RepairClimbObject.DEATH_PLATEAU){
player.inventory.remove(Item(nails.itemId,4))
}
player.inventory.remove(*requiredItems)
} else {
player.dialogueInterpreter.sendDialogue("You need a hammer and ${requiredItems.map { "${it.amount} ${it.name.toLowerCase()}s" }.toString().replace("[","").replace("]","")} for this.")
return
}
}
player.varpManager.get(rco.varp).setVarbit(rco.offset,1).send(player)
player.varpManager.flagSave(rco.varp)
}
private fun climb(player: Player, rco: RepairClimbObject, location: Location){
ForceMovement.run(player,location,rco.getOtherLocation(player),rco.getAnimation(player),rco.getAnimation(player),rco.getDirection(player),20).endAnimation = Animation(-1)
}
private enum class RepairClimbObject(val varp: Int, val offset: Int, val destinationUp: Location?, val destinationDown: Location?, val levelRequirement: Pair<Int,Int>?){
DEATH_PLATEAU(1282,15,Location.create(2949, 3623, 0),Location.create(2954, 3623, 0), Pair(Skills.CONSTRUCTION,42)),
BURTHORPE(1282,14,Location.create(2941, 3563, 0),Location.create(2934, 3563, 0),Pair(Skills.SMITHING,56)),
GWD(1283,27,null,null,Pair(Skills.CRAFTING,60)),
TEMPLE(1287,29,Location.create(2949, 3835, 0),Location.create(2956, 3835, 0),Pair(Skills.SMITHING,64));
fun getOtherLocation(player: Player): Location?{
if(player.location == destinationDown) return destinationUp
else return destinationDown
}
fun getAnimation(player: Player): Animation {
if(getOtherLocation(player) == destinationDown) return Animation(1148)
else return Animation(740)
}
fun getDirection(player: Player): Direction {
if(this == BURTHORPE){
return Direction.EAST
} else return Direction.WEST
}
fun isRepaired(player: Player): Boolean{
return player.varpManager.get(varp).getVarbit(offset)?.value == 1
}
}
companion object {
fun isRepaired(player: Player, beacon: AFUBeacon): Boolean{
if(beacon == AFUBeacon.DEATH_PLATEAU) return RepairClimbObject.DEATH_PLATEAU.isRepaired(player)
if(beacon == AFUBeacon.BURTHORPE) return RepairClimbObject.BURTHORPE.isRepaired(player)
if(beacon == AFUBeacon.GWD) return RepairClimbObject.GWD.isRepaired(player)
if(beacon == AFUBeacon.TEMPLE) return RepairClimbObject.TEMPLE.isRepaired(player)
else return true
}
}
}
@@ -1,131 +0,0 @@
package core.game.content.activity.allfiredup
import core.game.node.entity.player.Player
import core.game.node.item.Item
import core.game.system.SystemLogger
import core.game.system.task.Pulse
import core.game.world.GameWorld
import core.plugin.Plugin
import core.tools.Items
import core.tools.stringtools.colorize
/**
* Handles keeping track of lit beacons and their burn time remaining
* @author Ceikry
*/
class AFUSession(val player: Player) {
private val beaconTimers = Array(14){i -> BeaconTimer(0,AFUBeacon.values()[i])}
private val logInventories = Array(14){Item(0,0)}
private val beaconWatched = Array(14){false}
private var isActive = false
fun init() {
isActive = true
GameWorld.Pulser.submit(object: Pulse(){
override fun pulse(): Boolean {
player.setAttribute("afu-pulse",this)
beaconTimers.forEach {timer ->
timer.ticks--
if(timer.ticks == 300) timer.beacon.diminish(player).also {
if(beaconWatched[timer.beacon.ordinal]){
beaconWatched[timer.beacon.ordinal] = false
timer.ticks += (getTicks(logInventories[timer.beacon.ordinal].id) * 5)
timer.beacon.light(player)
player.sendMessage(colorize("%RThe ${timer.beacon.name.toLowerCase().replace("_"," ")} watcher has used your backup logs."))
} else {
player.sendMessage(colorize("%RThe ${timer.beacon.name.toLowerCase().replace("_", " ")} beacon is dying!"))
}
}
if(timer.ticks == 0) timer.beacon.extinguish(player).also { player.sendMessage(colorize("%RThe ${timer.beacon.name.toLowerCase().replace("_"," ")} beacon has gone out!")) }
}
return !isActive
}
})
player.setAttribute("afu-session",this)
player.logoutPlugins.add(AFULogoutPlugin())
}
fun getLitBeacons(): Int{
return beaconTimers.count { it.ticks > 0 }
}
fun end(){
isActive = false
}
fun setLogs(beaconIndex: Int, logs: Item){
logInventories[beaconIndex] = logs
}
fun startTimer(beaconIndex: Int){
val ticks = getTicks(logInventories[beaconIndex].id) * 20
logInventories[beaconIndex] = Item(0,0)
beaconTimers[beaconIndex].ticks = ticks
}
fun refreshTimer(beacon: AFUBeacon, logID: Int){
val ticks = getTicks(logID) * 5
beaconTimers.forEach {
if(it.beacon.ordinal == beacon.ordinal) it.ticks += ticks
}
}
fun setWatcher(index: Int, logs: Item){
beaconWatched[index] = true
logInventories[index] = logs
}
fun isWatched(index: Int): Boolean{
return beaconWatched[index]
}
fun getTicks(logID: Int): Int{
val ticks = when(logID){
Items.LOGS_1511 -> 65
Items.OAK_LOGS_1521 -> 68
Items.WILLOW_LOGS_1519 -> 73
Items.MAPLE_LOGS_1517 -> 79
Items.YEW_LOGS_1515 -> 83
Items.MAGIC_LOGS_1513 -> 90
else -> 0
}
return ticks
}
fun getBonusExperience(): Double{
return when(getLitBeacons()){
1 -> 608.4
2 -> 1622.4
3 -> 1987.4
4 -> 2149.6
5 -> 2149.6
6 -> 2514.6
7 -> 2555.2
8 -> 2758.0
9 -> 2839.1
10 -> 3041.9
11 -> 3123.0
12 -> 3244.7
13 -> 3366.4
14 -> 4867.4
else -> 0.0
}
}
internal class BeaconTimer(var ticks: Int, val beacon: AFUBeacon)
class AFULogoutPlugin: Plugin<Player> {
override fun newInstance(arg: Player?): Plugin<Player> {
arg ?: return this
AFUBeacon.resetAllBeacons(arg)
val session: AFUSession? = arg.getAttribute("afu-session",null)
session?.end()
arg.removeAttribute("afu-session")
return this
}
override fun fireEvent(identifier: String?, vararg args: Any?): Any {
return Unit
}
}
}
@@ -1,91 +0,0 @@
package core.game.content.activity.allfiredup
import core.game.node.entity.npc.NPC
import core.game.node.entity.player.Player
import core.game.node.item.Item
import core.plugin.Initializable
import core.tools.Items
import core.game.content.dialogue.DialoguePlugin
import core.game.node.entity.skill.Skills
private val VALID_LOGS = arrayOf(Items.LOGS_1511, Items.OAK_LOGS_1521, Items.WILLOW_LOGS_1519, Items.MAPLE_LOGS_1517, Items.YEW_LOGS_1515, Items.MAGIC_LOGS_1513)
@Initializable
//TODO: Add requirements for beacon keepers to watch beacons, most of the requirements were not possible to implement at the time of writing this.
class BeaconTenderDialogue(player: Player? = null) : DialoguePlugin(player) {
var index = 0
override fun newInstance(player: Player?): DialoguePlugin {
return BeaconTenderDialogue(player)
}
override fun open(vararg args: Any?): Boolean {
index = getIndexOf((args[0] as NPC).originalId)
if(index == AFUBeacon.GWD.ordinal && player.skills.getLevel(Skills.SUMMONING) < 81){
npc("Awwf uurrrhur","(You need 81 Summoning to communicate with Nanuq.)")
stage = 1000
return true
}
if(index == AFUBeacon.MONASTERY.ordinal && player.skills.getLevel(Skills.PRAYER) < 53){
npc("I will aid you when your devotion is","strong enough.","(You need 53 Prayer for him to watch the beacon.)")
stage = 1000
return true
}
npc = (args[0] as NPC).getShownNPC(player)
npc("Hello, adventurer.")
return true
}
override fun handle(interfaceId: Int, buttonId: Int): Boolean {
val beacon = AFUBeacon.values()[index]
val logs = getLogs(player,5)
val session: AFUSession? = player.getAttribute("afu-session",null)
when(stage){
0 -> player("Hello!").also { stage++ }
1 -> if(beacon.getState(player) == BeaconState.LIT && session?.isWatched(index) == false){
options("Can you watch this beacon for me?","Nevermind.").also { stage = 10 }
} else {
npc("Carry on, adventurer.").also { stage = 1000 }
}
10 -> when(buttonId){
1 -> player("Can you watch this beacon for me?").also { stage++ }
2 -> player("Nevermind.").also { stage = 1000 }
}
11 -> npc("Certainly, adventurer. Do you have logs for me?").also { stage++ }
12 -> if(logs.id != 0){
player("Yes, I do!").also { stage++ }
} else {
player("No, I don't.").also { stage = 1000 }
}
13 -> npc("Great, hand them over.").also { stage++ }
14 -> player("Here you go!").also {
player.inventory.remove(logs)
session?.setWatcher(index,logs)
stage = 1000
}
1000 -> end()
}
return true
}
fun getIndexOf(id: Int): Int{
if(id == 8065) return 0
if(id == 8066) return 1
for(index in ids.indices){
if(ids[index] == id) return index + 2
}
return -1
}
fun getLogs(player: Player, amount: Int): Item {
var logId = 0
for (log in VALID_LOGS) if (player.inventory.getAmount(log) >= amount) {logId = log; break}
return Item(logId,amount)
}
override fun getIds(): IntArray {
return intArrayOf(8067,8068,8069,8070,8071,8072,8073,8074,8075,8076)
}
}
@@ -1,47 +0,0 @@
package core.game.content.activity.allfiredup
import core.game.content.dialogue.DialogueFile
import core.game.node.item.Item
import core.tools.END_DIALOGUE
import core.tools.Items
import core.tools.START_DIALOGUE
class KingRoaldAFUMiniDialogue : DialogueFile() {
override fun handle(componentID: Int, buttonID: Int) {
when(stage){
START_DIALOGUE -> npc("Did what?").also { stage++ }
1 -> {
if (player!!.getAttribute("afu-mini:adze", false)) {
player("I lit all 14 beacons at once!")
} else if (player!!.getAttribute("afu-mini:gloves", false)) {
player("I lit 10 beacons at once!")
} else if (player!!.getAttribute("afu-mini:ring", false)) {
player("I lit 6 beacons at once!")
}
stage++
}
2 -> {
npc("Oh, wonderful! Here is your reward then.")
if (player!!.getAttribute(
"afu-mini:adze",
false
)
) if (player!!.inventory.add(Item(Items.INFERNO_ADZE_13661))) player!!.removeAttribute("afu-mini:adze")
if (player!!.getAttribute(
"afu-mini:gloves",
false
)
) if (player!!.inventory.add(Item(Items.FLAME_GLOVES_13660))) player!!.removeAttribute("afu-mini:gloves")
if (player!!.getAttribute(
"afu-mini:ring",
false
)
) if (player!!.inventory.add(Item(Items.RING_OF_FIRE_13659))) player!!.removeAttribute("afu-mini:ring")
stage = END_DIALOGUE
}
END_DIALOGUE -> end()
}
}
}
@@ -1,101 +0,0 @@
package core.game.content.activity.barrows
import core.game.component.Component
import core.game.container.access.InterfaceContainer
import core.game.content.global.BossKillCounter
import core.game.node.entity.player.Player
import core.game.node.item.GroundItemManager
import core.game.node.item.Item
import core.game.node.item.WeightedChanceItem
import core.tools.Components
import core.tools.Items
import core.tools.RandomFunction
import java.util.*
/**
* The reward chest.
* @author Ceikry
* and slightly kermit
*/
object RewardChest {
/**
* The low profit drop table.
*/
private val DROP_TABLE = arrayOf(
//Weighted total = 3050
WeightedChanceItem(Items.COINS_995, 1, 5306, 950),
WeightedChanceItem(Items.MIND_RUNE_558, 60, 60, 300),
WeightedChanceItem(Items.MIND_RUNE_558, 100, 850, 300),
WeightedChanceItem(Items.CHAOS_RUNE_562, 115, 720, 300),
WeightedChanceItem(Items.DEATH_RUNE_560, 15, 15, 300),
WeightedChanceItem(Items.DEATH_RUNE_560, 70, 230, 300),
WeightedChanceItem(Items.BLOOD_RUNE_565, 35, 230, 300),
WeightedChanceItem(Items.BOLT_RACK_4740, 35, 280, 300),
//Weight total = 975
WeightedChanceItem(Items.SUPER_DEFENCE2_165, 1, 1, 325),
WeightedChanceItem(Items.PRAYER_POTION2_141, 1, 1, 325),
WeightedChanceItem(Items.RESTORE_POTION2_129, 1, 1, 325),
//Weight total = 53
WeightedChanceItem(Items.TOOTH_HALF_OF_A_KEY_985, 1, 1, 25),
WeightedChanceItem(Items.LOOP_HALF_OF_A_KEY_987, 1, 1, 25),
WeightedChanceItem(Items.DRAGON_MED_HELM_1149, 1, 1, 3),
//Weight total = 120 BARROWS ITEMS V
WeightedChanceItem(4708, 1, 1, 5),
WeightedChanceItem(4710, 1, 1, 5),
WeightedChanceItem(4712, 1, 1, 5),
WeightedChanceItem(4714, 1, 1, 5),
WeightedChanceItem(4716, 1, 1, 5),
WeightedChanceItem(4718, 1, 1, 5),
WeightedChanceItem(4720, 1, 1, 5),
WeightedChanceItem(4722, 1, 1, 5),
WeightedChanceItem(4724, 1, 1, 5),
WeightedChanceItem(4726, 1, 1, 5),
WeightedChanceItem(4728, 1, 1, 5),
WeightedChanceItem(4730, 1, 1, 5),
WeightedChanceItem(4732, 1, 1, 5),
WeightedChanceItem(4734, 1, 1, 5),
WeightedChanceItem(4736, 1, 1, 5),
WeightedChanceItem(4738, 1, 1, 5),
WeightedChanceItem(4745, 1, 1, 5),
WeightedChanceItem(4747, 1, 1, 5),
WeightedChanceItem(4749, 1, 1, 5),
WeightedChanceItem(4751, 1, 1, 5),
WeightedChanceItem(4753, 1, 1, 5),
WeightedChanceItem(4755, 1, 1, 5),
WeightedChanceItem(4757, 1, 1, 5),
WeightedChanceItem(4759, 1, 1, 5)
)
/**
* Rewards the player.
*
* @param player The player.
*/
@JvmStatic
fun reward(player: Player) {
for (killed in player.savedData.activityData.barrowBrothers) {
if (!killed){
player.sendMessage("You can't loot the chest until you kill all 6 barrows brothers.")
player.removeAttribute("barrow:looted")
// Because they haven't
// actually looted the
// chest yet.
return
}
}
val rewards: MutableList<Item> = ArrayList()
var maxRolls = 2 + RandomFunction.random(0,player.savedData.activityData.barrowKills / 3)
if(maxRolls > 6) maxRolls = 6
for (i in 0 until maxRolls) {
rewards.add(RandomFunction.rollWeightedChanceTable(*DROP_TABLE))
}
InterfaceContainer.generateItems(player, rewards.toTypedArray(), arrayOf("Pog!","Examine"), 364, 4,3,4)
player.interfaceManager.open(Component(Components.trail_reward_364))
BossKillCounter.addtoBarrowsCount(player)
for(item in rewards){
if(!player.inventory.add(item)){
GroundItemManager.create(item,player)
}
}
}
}
@@ -1,89 +0,0 @@
package core.game.content.activity.fishingtrawler
import core.game.node.entity.player.Player
import core.game.system.task.Pulse
import core.game.world.GameWorld
import core.game.world.map.Location
import core.game.world.map.build.DynamicRegion
import core.game.world.map.zone.ZoneRestriction
import core.plugin.Initializable
import core.tools.ticksToSeconds
import core.game.content.activity.ActivityManager
import core.game.content.activity.ActivityPlugin
import core.tools.stringtools.colorize
/**
* Handles the fishing trawler "waiting room"
* @author Ceikry
*/
private val WAIT_TIME = if(GameWorld.settings?.isDevMode == true) 10 else 203
private val waitingPlayers = ArrayList<Player>()
private val sessions = ArrayList<FishingTrawlerSession>()
private var activity: FishingTrawlerActivity? = null
private var nextStart = GameWorld.ticks + WAIT_TIME
@Initializable
class FishingTrawlerActivity : ActivityPlugin("fishing trawler",false,false,true,ZoneRestriction.CANNON,ZoneRestriction.FIRES,ZoneRestriction.FOLLOWERS,ZoneRestriction.RANDOM_EVENTS) {
init {
activity = this
}
override fun configure() {
GameWorld.Pulser.submit(
object : Pulse(1){
override fun pulse(): Boolean {
if((nextStart - GameWorld.ticks) % 100 == 0){
for(player in waitingPlayers) {
player.sendMessage (colorize("%R${ticksToSeconds(nextStart - GameWorld.ticks) / 60} minutes until next game."))
}
}
if(GameWorld.ticks >= nextStart && waitingPlayers.isNotEmpty()){
val session = FishingTrawlerSession(DynamicRegion.create(8011), activity!!)
session.start(waitingPlayers)
sessions.add(session)
waitingPlayers.clear()
nextStart = GameWorld.ticks + WAIT_TIME
}
sessions.removeIf { session ->
if(!session.isActive && session.inactiveTicks >= 100){
session.clearNPCs()
true
} else {
if(!session.isActive) {
session.inactiveTicks++
}
false
}
}
return false
}
})
}
override fun start(player: Player?, login: Boolean, vararg args: Any?): Boolean {
player ?: return false
waitingPlayers.add(player)
return true
}
fun addPlayer(player: Player){
if(waitingPlayers.isEmpty()) {
nextStart = GameWorld.ticks + WAIT_TIME
player.dialogueInterpreter.sendDialogue("Trawler will leave in 2 minutes.","If you have a team get them on board now!")
}
waitingPlayers.add(player)
}
fun removePlayer(player: Player){
waitingPlayers.remove(player)
}
override fun newInstance(p: Player?): ActivityPlugin {
ActivityManager.register(this)
return this
}
override fun getSpawnLocation(): Location {
return Location.create(2667, 3161, 0)
}
}
@@ -1,241 +0,0 @@
package core.game.content.activity.fishingtrawler
import core.cache.def.impl.ItemDefinition
import core.cache.def.impl.ObjectDefinition
import core.game.interaction.OptionHandler
import core.game.node.Node
import core.game.node.entity.player.Player
import core.game.node.entity.player.info.stats.FISHING_TRAWLER_LEAKS_PATCHED
import core.game.node.entity.player.info.stats.STATS_BASE
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 core.game.world.update.flag.context.Animation
import core.plugin.Initializable
import core.plugin.Plugin
import core.tools.Items
import core.game.content.activity.ActivityManager
import core.game.content.dialogue.DialoguePlugin
import core.game.content.dialogue.FacialExpression
import core.game.node.entity.skill.Skills
import core.tools.stringtools.colorize
import kotlin.math.ceil
/**
* Option handler for fishing trawler
* @author Ceikry
*/
@Initializable
class FishingTrawlerOptionHandler : OptionHandler() {
override fun newInstance(arg: Any?): Plugin<Any> {
ObjectDefinition.forId(2178).handlers["option:cross"] = this
ObjectDefinition.forId(2167).handlers["option:fill"] = this
ObjectDefinition.forId(2164).handlers["option:inspect"] = this
ObjectDefinition.forId(2165).handlers["option:inspect"] = this
ObjectDefinition.forId(2166).handlers["option:inspect"] = this
ObjectDefinition.forId(2160).handlers["option:climb-on"] = this
ObjectDefinition.forId(2159).handlers["option:climb-on"] = this
ObjectDefinition.forId(2179).handlers["option:cross"] = this
ObjectDefinition.forId(255).handlers["option:operate"] = this
ItemDefinition.forId(583).handlers["option:bail-with"] = this
ItemDefinition.forId(585).handlers["option:empty"] = this
return this
}
override fun handle(player: Player?, node: Node?, option: String?): Boolean {
player ?: return false
when(node?.id){
2178 -> { //Cross plank onto boat
if(player.skills.getLevel(Skills.FISHING) < 15){
player.dialogueInterpreter.sendDialogue("You need to be at least level 15 fishing to play.")
return true
}
player.properties.teleportLocation = Location.create(2672, 3170, 1)
(ActivityManager.getActivity("fishing trawler") as FishingTrawlerActivity).addPlayer(player)
}
2167 -> { //Fill hole
val session: FishingTrawlerSession? = player.getAttribute("ft-session",null)
session ?: return false
player.lock()
player.pulseManager.run(object : Pulse(){
var counter = 0
override fun pulse(): Boolean {
when(counter++){
0 -> player.animator.animate(Animation(827)).also { player.lock() }
1 -> session.repairHole(player,node.asObject()).also { player.incrementAttribute("/save:$STATS_BASE:$FISHING_TRAWLER_LEAKS_PATCHED"); player.unlock() }
2 -> return true
}
return false
}
})
}
2164,2165 -> { //inspect net
player.dialogueInterpreter.open(18237583)
}
2166 -> { //inspect reward net
val session: FishingTrawlerSession? = player.getAttribute("ft-session",null)
if(session == null || session.boatSank){
player.dialogueInterpreter.sendDialogues(player, FacialExpression.GUILTY,"I'd better not go stealing other people's fish.")
return true
}
player.dialogueInterpreter.open(18237582)
}
2179 -> { //plank from boat to dock
player.properties.teleportLocation = Location.create(2676, 3170, 0)
(ActivityManager.getActivity("fishing trawler") as FishingTrawlerActivity).removePlayer(player)
val session: FishingTrawlerSession? = player.getAttribute("ft-session",null)
session?.players?.remove(player)
player.logoutPlugins.clear()
}
2159,2160 -> { //barrel
player.properties.teleportLocation = Location.create(2672, 3222, 0)
player.dialogueInterpreter.sendDialogue("You climb onto the floating barrel and begin to kick your way to the","shore.","You make it to the shore tired and weary.")
player.logoutPlugins.clear()
player.appearance.setDefaultAnimations()
player.appearance.sync()
}
583 -> { //bail-with bucket
val session: FishingTrawlerSession? = player.getAttribute("ft-session",null)
session ?: return false
if(!session.isActive){
return false
}
if(player.location.y > 0){
player.sendMessage("You can't scoop water out up here.")
return true
}
player.lock()
player.pulseManager.run(
object : Pulse(){
var counter = 0
override fun pulse(): Boolean {
when(counter++){
0 -> player.animator.animate(Animation(4471))
1 -> if(player.inventory.remove(node.asItem())) {
if (session.waterAmount > 0) {
session.waterAmount -= 20
if (session.waterAmount < 0) session.waterAmount = 0
player.inventory.add(Item(Items.BAILING_BUCKET_585))
} else {
player.sendMessage("There's no water to remove.")
player.inventory.add(node.asItem())
}
}
2 -> player.unlock().also { return true }
}
return false
}
}
)
}
585 -> { //Empty bailing bucket
player.lock()
player.pulseManager.run(
object : Pulse(){
var counter = 0
override fun pulse(): Boolean {
when(counter++){
0 -> player.animator.animate(Animation(2450))
1 -> {
if(player.inventory.remove(node.asItem()))
player.inventory.add(Item(Items.BAILING_BUCKET_583))
player.unlock()
return true
}
}
return false
}
}
)
}
255 -> {//operate winch
player.sendMessage("It seems the winch is jammed - I can't move it.")
}
}
return true
}
}
@Initializable
class NetLootDialogue(player: Player? = null): DialoguePlugin(player){
var session: FishingTrawlerSession? = null
var rolls = 0
override fun newInstance(player: Player?): DialoguePlugin {
return NetLootDialogue(player)
}
override fun open(vararg args: Any?): Boolean {
session = player.getAttribute("ft-session",null)
if(session == null) return false
rolls = ceil(session!!.fishAmount / session!!.players.size.toDouble()).toInt()
player.dialogueInterpreter.sendOptions("Skip Junk Items?","Yes","No")
stage = 0
return true
}
override fun handle(interfaceId: Int, buttonId: Int): Boolean {
when(buttonId){
1 -> TrawlerLoot.getLoot(rolls,true).forEach {
if(!player.bank.add(it)) GroundItemManager.create(it,player)
}
2 -> TrawlerLoot.getLoot(rolls,false).forEach {
if(!player.bank.add(it)) GroundItemManager.create(it,player)
}
}
player.sendMessage(colorize("%RYour reward has been sent to your bank."))
player.skills.addExperience(Skills.FISHING,(((0.015 * player.skills.getLevel(Skills.FISHING))) * player.skills.getLevel(Skills.FISHING)) * rolls)
player.removeAttribute("ft-session")
end()
return true
}
override fun getIds(): IntArray {
return intArrayOf(18237582)
}
}
@Initializable
class NetRepairDialogue(player: Player? = null) : DialoguePlugin(player){
var session: FishingTrawlerSession? = null
override fun newInstance(player: Player?): DialoguePlugin {
return NetRepairDialogue(player)
}
override fun open(vararg args: Any?): Boolean {
session = player.getAttribute("ft-session",null)
if(session!!.netRipped){
player.dialogueInterpreter.sendDialogue("The net is ripped and needs repair.")
stage = 10
} else {
player.dialogueInterpreter.sendDialogue("The net is in perfect condition")
stage = 0
}
return true
}
override fun handle(interfaceId: Int, buttonId: Int): Boolean {
session ?: return false
when(stage++){
0 -> end()
10 -> player.dialogueInterpreter.sendOptions("Repair the net?","Yes","No")
11 -> when(buttonId){
1 -> {
end()
session!!.repairNet(player)
}
else -> {}
}
12 -> end()
}
return true
}
override fun getIds(): IntArray {
return intArrayOf(18237583)
}
}
@@ -1,26 +0,0 @@
package core.game.content.activity.fishingtrawler
import core.game.node.entity.player.Player
private const val configIndex = 391
private const val interfaceID = 366
private const val netOkayChild = 27
private const val netRippedChild = 28
private const val fishChild = 29
private const val timeChild = 30
/**
* Handles updating the fishing trawler overlay interface
* @author Ceikry
*/
object FishingTrawlerOverlay {
@JvmStatic
fun sendUpdate(player: Player, waterPercent: Int, NetRipped: Boolean, fishCaught: Int, timeLeft: Int){
player.configManager.set(configIndex,waterPercent)
player.packetDispatch.sendInterfaceConfig(interfaceID,if(NetRipped) netRippedChild else netOkayChild, false)
player.packetDispatch.sendInterfaceConfig(interfaceID,if(NetRipped) netOkayChild else netRippedChild, true)
player.packetDispatch.sendString("${if(fishCaught > 0) fishCaught else "Nothing"}",interfaceID,fishChild)
player.packetDispatch.sendString("$timeLeft Minutes", interfaceID, timeChild)
}
}
@@ -1,42 +0,0 @@
package core.game.content.activity.fishingtrawler
import core.game.component.Component
import core.game.component.ComponentDefinition
import core.game.component.ComponentPlugin
import core.game.node.entity.player.Player
import core.game.node.item.Item
import core.plugin.Plugin
import kotlin.math.ceil
/**
* THIS will have to be implemented at a later date.
* Interface 367 in our cache, for whatever reason, opens correctly but all the children
* are null or cant hold items. This interface cant even be opened in 2 different versions
* of a cache editor I have. Something is completely fucked about this interface
* in particular.
*/
class FishingTrawlerRewardInterface : ComponentPlugin() {
override fun newInstance(arg: Any?): Plugin<Any> {
ComponentDefinition.put(367,this)
return this
}
override fun open(player: Player?, component: Component?) {
super.open(player, component)
val session: FishingTrawlerSession? = player?.getAttribute("ft-session",null)
session ?: return
val numRolls = ceil(session.fishAmount / session.players.size.toDouble()).toInt()
player?.removeAttribute("ft-session")
val loot = ArrayList<Item>()
for(i in 0 until numRolls){
}
}
override fun handle(player: Player?, component: Component?, opcode: Int, button: Int, slot: Int, itemId: Int): Boolean {
TODO("Not yet implemented")
}
}
@@ -1,276 +0,0 @@
package core.game.content.activity.fishingtrawler
import core.game.component.Component
import core.game.node.`object`.GameObject
import core.game.node.`object`.ObjectBuilder
import core.game.node.entity.npc.NPC
import core.game.node.entity.player.Player
import core.game.node.entity.player.info.stats.FISHING_TRAWLER_GAMES_WON
import core.game.node.entity.player.info.stats.FISHING_TRAWLER_SHIPS_SANK
import core.game.node.entity.player.info.stats.STATS_BASE
import core.game.node.entity.state.EntityState
import core.game.node.item.Item
import core.game.system.task.Pulse
import core.game.world.GameWorld
import core.game.world.map.Location
import core.game.world.map.build.DynamicRegion
import core.game.world.update.flag.context.Animation
import core.plugin.Plugin
import core.tools.*
import java.util.concurrent.TimeUnit
import kotlin.random.Random
/**
* Handles a fishing trawler session
* @author Ceikry
*/
private const val OVERLAY_ID = Components.trawler_overlay_366
private const val TUTORIAL_ID = Components.trawler_start_368
private val HOLE_X_COORDS = intArrayOf(29,30,31,32,33,34,35,36)
private const val HOLE_NORTH_Y = 26
private const val HOLE_SOUTH_Y = 23
private const val LEAKING_ID = 2167
private const val PATCHED_ID = 2168
class FishingTrawlerSession(var region: DynamicRegion, val activity: FishingTrawlerActivity) {
var players: ArrayList<Player> = ArrayList()
var netRipped = false
var fishAmount = 0
var timeLeft = secondsToTicks(600)
var base = region.baseLocation
var isActive = false
var boatSank = false
var hole_locations = ArrayList<Location>()
var used_locations = ArrayList<Location>()
var maxHoles = 0
var waterAmount = 0
var murphy: NPC? = null
val murphyLocations = ArrayList<Location>()
val npcs = ArrayList<NPC>()
var inactiveTicks = 0
fun start(pl: ArrayList<Player>){
this.players.addAll(pl)
isActive = true
initHoles()
initMurphy(29,25)
initGulls()
GameWorld.Pulser.submit(TrawlerPulse(this))
for(player in pl){
player.interfaceManager.openOverlay(Component(OVERLAY_ID))
player.interfaceManager.open(Component(TUTORIAL_ID))
updateOverlay(player)
player.properties.teleportLocation = base.transform(36,24,0)
player.setAttribute("ft-session",this)
player.logoutPlugins.add(TrawlerLogoutPlugin())
player.stateManager.set(EntityState.TELEBLOCK,timeLeft)
}
}
fun swapBoatType(fromRegion: Int){
val newRegion = DynamicRegion.create(fromRegion)
GameWorld.Pulser.submit(SwapBoatPulse(players,newRegion))
}
class SwapBoatPulse(val playerList: ArrayList<Player>,val newRegion: DynamicRegion) : Pulse(3){
override fun pulse(): Boolean {
val session: FishingTrawlerSession? = playerList[0].getAttribute("ft-session",null)
session ?: return true
session.region = newRegion
session.base = newRegion.baseLocation
session.clearNPCs()
session.initMurphy(26,26)
session.initGulls()
for(player in playerList){
player.interfaceManager.closeOverlay()
player.appearance.setAnimations(Animation(188))
player.properties.teleportLocation = session.base.transform(36,24,0)
player.incrementAttribute("/save:$STATS_BASE:$FISHING_TRAWLER_SHIPS_SANK")
player.stateManager.remove(EntityState.TELEBLOCK)
}
return true
}
}
class TrawlerPulse(val session: FishingTrawlerSession) : Pulse(){
var ticks = 0
override fun pulse(): Boolean {
ticks++
session.timeLeft--
if(session.boatSank){
session.tickMurphy()
return true
}
if(ticks % 15 == 0 && !session.netRipped){
if(RandomFunction.random(100) <= 10){
session.ripNet()
session.murphy?.sendChat("Arrh! Check that net!")
} else {
session.fishAmount += 3
}
}
session.waterAmount += (session.getLeakingHoles())
if(session.waterAmount >= 500){
session.boatSank = true
session.isActive = false
session.swapBoatType(7755)
}
if(RandomFunction.random(100) <= 9){
session.spawnHole()
}
if(session.timeLeft <= 0){
session.isActive = false
for(player in session.players){
player.interfaceManager.closeOverlay()
player.properties.teleportLocation = Location.create(2666, 3162, 0)
player.logoutPlugins.clear()
player.incrementAttribute("/save:$STATS_BASE:$FISHING_TRAWLER_GAMES_WON")
}
}
for(player in session.players){
session.updateOverlay(player)
}
session.tickMurphy()
return !session.isActive
}
}
fun initHoles(){
maxHoles = players.size
if(maxHoles > 16) maxHoles = 16
if(maxHoles < 5) maxHoles = 5
val tempLocationList = ArrayList<Location>()
while(tempLocationList.size < maxHoles){
val x = HOLE_X_COORDS.random()
val y = if(Random.nextBoolean()) HOLE_NORTH_Y else HOLE_SOUTH_Y
val loc = Location.create(x,y,0)
var alreadyHas = false
for(location in tempLocationList){
if(location.equals(loc)) {
alreadyHas = true
break
}
}
if(!alreadyHas) {
tempLocationList.add(base.transform(loc.x, loc.y, 0))
}
}
hole_locations.addAll(tempLocationList)
}
fun initMurphy(localX: Int, localY: Int){
murphy = NPC(463)
murphy?.isWalks = false
murphy?.isPathBoundMovement = true
//29,25 -> 36,25
murphy?.location = base.transform(localX,localY,0)
murphy?.isRespawn = false
for(i in 29..36){
murphyLocations.add(Location.create(base.transform(i,25,0)))
}
murphy?.init()
npcs.add(murphy!!)
}
fun clearNPCs(){
npcs.forEach {
it.clear()
}
npcs.clear()
}
fun tickMurphy(){
var phrase = if(boatSank){
arrayOf("No fishes for you today!","Keep your head above water, shipmate.", "Arrrgh! We sunk!","You'll be joining Davy Jones!").random()
} else if(waterAmount < 200){
arrayOf("Blistering barnacles!","Let's get a net full of fishes!").random()
} else {
arrayOf("We'll all end up in a watery grave!","My mother could bail better than that!","It's a fierce sea today traveller.").random()
}
if(getLeakingHoles() > 0 && RandomFunction.random(100) <= 15){
phrase = "The water is coming in matey!"
}
if(RandomFunction.random(100) <= 10){
murphy?.sendChat(phrase)
}
if(RandomFunction.random(100) <= 6){
val dest = murphyLocations.random()
murphy?.walkingQueue?.reset()
murphy?.walkingQueue?.addPath(dest.x,dest.y,true)
}
}
fun initGulls(){
for(loc in arrayOf(base.transform(38,17,0),base.transform(33,18,0),base.transform(28,16,0),base.transform(28,30,0),base.transform(34,32,0))){
val npc = NPC(1179)
npc.location = loc
npcs.add(npc)
npc.isRespawn = false
npc.isWalks = true
npc.walkRadius = 6
npc.init()
}
}
fun spawnHole(){
if(hole_locations.isEmpty() && used_locations.isEmpty()) return
val holeLocation = hole_locations.random().also { hole_locations.remove(it) }
if(!ObjectBuilder.replace(GameObject(PATCHED_ID, holeLocation), GameObject(LEAKING_ID, holeLocation, if (holeLocation.y == HOLE_NORTH_Y) 1 else 3)) && !ObjectBuilder.replace(GameObject(2177, holeLocation), GameObject(LEAKING_ID, holeLocation, if (holeLocation.y == HOLE_NORTH_Y) 1 else 3))) {
maxHoles -= 1
}
}
fun getLeakingHoles(): Int{
return maxHoles - hole_locations.size
}
fun repairHole(player: Player,obj: GameObject){
if(player.inventory.remove(Item(Items.SWAMP_PASTE_1941))){
ObjectBuilder.replace(obj,GameObject(PATCHED_ID,obj.location,obj.rotation))
hole_locations.add(obj.location)
if(RandomFunction.random(100) <= 30){
murphy?.sendChat("That's the stuff! Fill those holes!")
}
} else {
player.dialogueInterpreter.sendDialogue("You need swamp paste to repair this.")
}
}
fun ripNet(){
netRipped = true
}
fun repairNet(player: Player){
if(player.inventory.remove(Item(Items.ROPE_954))){
netRipped = false
player.dialogueInterpreter.sendDialogue("You repair the net.")
} else {
player.dialogueInterpreter.sendDialogue("You need rope to repair this net.")
}
}
fun updateOverlay(player: Player){
FishingTrawlerOverlay.sendUpdate(player,((waterAmount / 500.0) * 100).toInt(),netRipped,fishAmount,TimeUnit.SECONDS.toMinutes(ticksToSeconds(timeLeft).toLong()).toInt() + 1)
}
}
class TrawlerLogoutPlugin : Plugin<Player>{
override fun newInstance(arg: Player?): Plugin<Player> {
arg?.location = Location.create(2667, 3161, 0)
val session: FishingTrawlerSession? = arg?.getAttribute("ft-session",null)
session ?: return this
session.players.remove(arg)
return this
}
override fun fireEvent(identifier: String?, vararg args: Any?): Any {
return Unit
}
}
@@ -1,56 +0,0 @@
package core.game.content.activity.fishingtrawler
import core.game.node.item.Item
import core.game.node.item.WeightedChanceItem
import core.tools.Items
import core.tools.RandomFunction
/**
* Rolls/stores the loot table for fishing trawler
* @author Ceikry
*/
object TrawlerLoot {
val junkItems = arrayOf(Items.BROKEN_ARMOUR_698, Items.BROKEN_ARROW_687, Items.OLD_BOOT_685, Items.BROKEN_GLASS_1469, Items.BROKEN_STAFF_689, Items.BUTTONS_688,Items.DAMAGED_ARMOUR_697, Items.RUSTY_SWORD_686, Items.EMPTY_POT_1931, Items.OYSTER_407)
@JvmStatic
fun getLoot(rolls: Int, skipJunk: Boolean): ArrayList<Item>{
val loot = ArrayList<Item>()
for(i in 0 until rolls){
loot.add(RandomFunction.rollWeightedChanceTable(listOf(*lootTable)))
}
if(skipJunk){
val removeList = ArrayList<Item>()
for(item in loot){
if(junkItems.contains(item.id)) removeList.add(item)
}
loot.removeAll(removeList)
}
return loot
}
val lootTable = arrayOf(
WeightedChanceItem(Items.RAW_SHRIMPS_317,1,150),
WeightedChanceItem(Items.RAW_SARDINE_327,1,150),
WeightedChanceItem(Items.RAW_ANCHOVIES_321,1,150),
WeightedChanceItem(Items.RAW_TUNA_359,1,140),
WeightedChanceItem(Items.RAW_LOBSTER_377,1,140),
WeightedChanceItem(Items.RAW_SWORDFISH_371,1,130),
WeightedChanceItem(Items.RAW_SHARK_383,1,120),
WeightedChanceItem(Items.RAW_SEA_TURTLE_395,1,120),
WeightedChanceItem(Items.RAW_MANTA_RAY_389,1,120),
WeightedChanceItem(Items.BROKEN_ARROW_687,1,70),
WeightedChanceItem(Items.BROKEN_GLASS_1469,1,70),
WeightedChanceItem(Items.BROKEN_STAFF_689,1,70),
WeightedChanceItem(Items.BUTTONS_688,1,80),
WeightedChanceItem(Items.DAMAGED_ARMOUR_697,1,70),
WeightedChanceItem(Items.OLD_BOOT_685,1,60),
WeightedChanceItem(Items.OYSTER_407,1,50),
WeightedChanceItem(Items.EMPTY_POT_1931,1,50),
WeightedChanceItem(Items.RUSTY_SWORD_686,1,50),
//Inauthentic rewards
WeightedChanceItem(Items.LOOP_HALF_OF_A_KEY_987,1,40),
WeightedChanceItem(Items.TOOTH_HALF_OF_A_KEY_985,1,40),
WeightedChanceItem(Items.CASKET_405,1,60),
WeightedChanceItem(Items.PIRATES_HAT_2651,1,2),
WeightedChanceItem(Items.LUCKY_CUTLASS_7140,1,2)
)
}
@@ -1,45 +0,0 @@
package core.game.content.activity.fog
import core.game.content.global.action.ClimbActionHandler
import core.game.interaction.DestinationFlag
import core.game.interaction.MovementPulse
import core.game.node.Node
import core.game.node.`object`.GameObject
import core.game.node.entity.player.Player
import core.plugin.Initializable
import core.plugin.Plugin
import core.game.content.quest.PluginInteraction
import core.game.content.quest.PluginInteractionManager
@Initializable
class FogInteractionHandler : PluginInteraction(30204, 30203){
override fun handle(player: Player?, node: Node?): Boolean {
when(node?.id){
30204 -> player?.pulseManager?.run(ClimbPulse(player,node as GameObject)).also { return true }
30203 -> player?.pulseManager?.run(ClimbPulse(player, node as GameObject)).also { return true }
}
return false
}
class ClimbPulse(val player: Player,val obj: GameObject) : MovementPulse(player,obj, DestinationFlag.OBJECT){
override fun pulse(): Boolean {
player.faceLocation(obj.location)
when(obj.id) {
30204 -> ClimbActionHandler.climbLadder(player, obj, "climb-down")
30203 -> ClimbActionHandler.climbLadder(player,obj,"climb-up")
}
return true
}
}
override fun fireEvent(identifier: String?, vararg args: Any?): Any {
return Unit
}
override fun newInstance(arg: Any?): Plugin<Any> {
PluginInteractionManager.register(this,PluginInteractionManager.InteractionType.OBJECT)
return this
}
}
@@ -1,66 +0,0 @@
package core.game.content.activity.fog
import core.game.component.Component
import core.game.node.entity.player.Player
import core.game.node.item.Item
import core.game.world.GameWorld
import core.plugin.Initializable
import core.game.interaction.FOGRewardsInterface
import core.game.content.dialogue.DialoguePlugin
import core.tools.Components
@Initializable
class ReggieDialogue(player: Player? = null) : DialoguePlugin(player){
override fun open(vararg args: Any?): Boolean {
if(GameWorld.settings?.allow_token_purchase == true){
options("Can I see your shop?","Nevermind.","Can I buy some tokens?")
} else {
options("Can I see your shop?","Nevermind.")
}
stage = 0
return true
}
override fun newInstance(player: Player?): DialoguePlugin {
FOGRewardsInterface().newInstance(Unit)
return ReggieDialogue(player)
}
override fun handle(interfaceId: Int, buttonId: Int): Boolean {
var buyAmount = 0
when(stage){
0 -> when(buttonId){
1 -> npc("Certainly!").also { stage++ }
2 -> end()
3 -> npc("Sure thing. My tokens are 1000 coins","each.").also { stage = 10 }
}
1 -> end().also { player.interfaceManager.open(Component(Components.fog_reward_732)) }
//Buying tokens with config option set to true
10 -> player?.dialogueInterpreter?.sendOptions("How many?","50","100","250","500").also { stage++ }
11 -> when(buttonId){
1 -> buyAmount = 50
2 -> buyAmount = 100
3 -> buyAmount = 250
4 -> buyAmount = 500
else -> buyAmount = 0
}.also {
if(buyAmount > 0){
if(player?.inventory?.containsItem(Item(995, 1000 * buyAmount))!!) {
player?.inventory?.add(Item(12852, buyAmount))
player?.inventory?.remove(Item(995, 1000 * buyAmount))
} else {
player?.sendMessage("You dont have enough coins for that.")
}
}
end()
}
}
return true
}
override fun getIds(): IntArray {
return intArrayOf(7601)
}
}
@@ -1,32 +0,0 @@
package core.game.content.activity.gnomecooking
import core.cache.def.impl.ItemDefinition
import core.game.interaction.OptionHandler
import core.game.node.Node
import core.game.node.entity.npc.NPC
import core.game.node.entity.player.Player
import core.game.node.item.Item
import core.plugin.Initializable
import core.plugin.Plugin
@Initializable
class DeliveryBoxHandler : OptionHandler() {
override fun newInstance(arg: Any?): Plugin<Any> {
ItemDefinition.forId(9477).handlers["option:check"] = this
return this
}
override fun handle(player: Player?, node: Node?, option: String?): Boolean {
player ?: return false
val jobId = player.getAttribute("$GC_BASE_ATTRIBUTE:$GC_JOB_ORDINAL",-1)
if(jobId == -1){
player.dialogueInterpreter.sendDialogue("You do not currently have a job.")
} else {
val job = GnomeCookingJob.values()[jobId]
val item = player.getAttribute("$GC_BASE_ATTRIBUTE:$GC_NEEDED_ITEM", Item(0))
player.dialogueInterpreter.sendDialogue("I need to deliver a ${item.name.toLowerCase()} to ${NPC(job.npc_id).name.toLowerCase()},","who is ${job.tip}")
}
return true
}
}
@@ -1,107 +0,0 @@
package core.game.content.activity.gnomecooking
import core.cache.def.impl.ItemDefinition
import core.tools.Items
import core.game.interaction.OptionHandler
import core.game.node.Node
import core.game.node.entity.player.Player
import core.game.node.item.Item
import core.game.system.task.Pulse
import core.game.world.GameWorld
import core.plugin.Initializable
import core.plugin.Plugin
import core.tools.RandomFunction
import core.game.content.dialogue.DialoguePlugin
val gnomeItems = arrayOf(Items.FRUIT_BATTA_2277, Items.TOAD_BATTA_2255, Items.CHEESE_PLUSTOM_BATTA_2259, Items.WORM_BATTA_2253, Items.VEGETABLE_BATTA_2281,
Items.CHOCOLATE_BOMB_2185, Items.VEG_BALL_2195, Items.TANGLED_TOADS_LEGS_2187, Items.WORM_HOLE_2191, Items.TOAD_CRUNCHIES_2217, Items.WORM_CRUNCHIES_2205, Items.CHOCCHIP_CRUNCHIES_2209, Items.SPICY_CRUNCHIES_2213)
@Initializable
class GCRewardTokenHandler : OptionHandler() {
override fun newInstance(arg: Any?): Plugin<Any> {
val def = ItemDefinition.forId(9474)
def.handlers["option:check"] = this
def.handlers["option:activate"] = this
return this
}
override fun handle(player: Player?, node: Node?, option: String?): Boolean {
player ?: return false
node ?: return false
option ?: return false
when(option){
"check" -> {
val charges = player.getAttribute("$GC_BASE_ATTRIBUTE:$GC_REDEEMABLE_FOOD",0)
player.dialogueInterpreter.sendDialogue("You have $charges redeemable charges.")
}
"activate" -> {
player.dialogueInterpreter.open(939382893)
}
}
return true
}
@Initializable
class RewardTokenActivationDialogue(player: Player? = null) : DialoguePlugin(player){
override fun newInstance(player: Player?): DialoguePlugin {
return RewardTokenActivationDialogue(player)
}
override fun open(vararg args: Any?): Boolean {
player.dialogueInterpreter.sendOptions("How many charges?","1","5","10")
stage = 0
return true
}
override fun handle(interfaceId: Int, buttonId: Int): Boolean {
when(stage){
0 -> end().also {
when (buttonId) {
1 -> sendCharges(1, player)
2 -> sendCharges(5, player)
3 -> sendCharges(10, player)
}
}
}
return true
}
fun sendCharges(amount: Int, player: Player){
val playerCharges = player.getAttribute("$GC_BASE_ATTRIBUTE:$GC_REDEEMABLE_FOOD",0)
if(playerCharges < amount){
player.dialogueInterpreter.sendDialogue("You don't have that many charges.")
return
}
if(player.inventory.freeSlots() < amount){
player.dialogueInterpreter.sendDialogue("You don't have enough space in your inventory.")
return
}
val itemList = ArrayList<Item>()
for(charge in 0 until amount){
itemList.add(Item(gnomeItems.random()))
}
player.dialogueInterpreter.sendDialogue("You put in for delivery of $amount items. Wait a bit...")
GameWorld.Pulser.submit(DeliveryPulse(player,itemList))
player.setAttribute("/save:$GC_BASE_ATTRIBUTE:$GC_REDEEMABLE_FOOD", playerCharges - amount)
}
class DeliveryPulse(val player: Player,val items: ArrayList<Item>) : Pulse(RandomFunction.random(15,30)){
override fun pulse(): Boolean {
player.inventory.add(*items.toTypedArray())
player.dialogueInterpreter.sendDialogue("Your food delivery has arrived!")
return true
}
}
override fun getIds(): IntArray {
return intArrayOf(939382893)
}
}
}
@@ -1,11 +0,0 @@
package core.game.content.activity.gnomecooking
const val GC_BASE_ATTRIBUTE = "gnome_cooking"
const val GC_TUT_PROG = "tutorial:stage"
const val GC_TUT_FIN = "tutorial:complete"
const val GC_JOB_ORDINAL = "job:job_ordinal"
const val GC_JOB_COMPLETE = "job:job_complete"
const val GC_HARD_JOB = "job:hard_job"
const val GC_NEEDED_ITEM = "job:needed_item"
const val GC_POINTS = "job:points"
const val GC_REDEEMABLE_FOOD = "job:redeemable_food"
@@ -1,19 +0,0 @@
package core.game.content.activity.gnomecooking
enum class GnomeCookingJob(val level: GnomeTipper.LEVEL, val npc_id: Int, val tip: String) {
CPT_ERRDO(GnomeTipper.LEVEL.EASY,3811, "at the top level of the Grand Tree."),
DALILAH(GnomeTipper.LEVEL.EASY,4588, "sitting in the Gnome Restaurant."),
GULLUCK(GnomeTipper.LEVEL.EASY,602, "on the third level of the Grand Tree."),
ROMETTI(GnomeTipper.LEVEL.EASY,601, "on the second level of the Grand Tree."),
NARNODE(GnomeTipper.LEVEL.EASY,670, "at the base of the Grand Tree."),
MEEGLE(GnomeTipper.LEVEL.EASY,4597, "in the terrorbird enclosure."),
PERRDUR(GnomeTipper.LEVEL.EASY,4587,"sitting in the Gnome Restaurant."),
SARBLE(GnomeTipper.LEVEL.EASY,4599, "in the swamp west of the Grand Tree."),
GIMLEWAP(GnomeTipper.LEVEL.HARD,4580, "upstairs in Ardougne castle."),
BLEEMADGE(GnomeTipper.LEVEL.HARD,3810, "at the top of White Wolf Mountain."),
DALBUR(GnomeTipper.LEVEL.HARD,3809, "by the gnome glider in Al Kharid"),
BOLREN(GnomeTipper.LEVEL.HARD,469, "next to the Spirit Tree in Tree Gnome Village"),
SCHEPBUR(GnomeTipper.LEVEL.HARD,3817, "in the battlefield of Khazar, south of the river."),
IMBLEWYN(GnomeTipper.LEVEL.HARD,4586, "on the ground floor of the Magic Guild."),
ONGLEWIP(GnomeTipper.LEVEL.HARD,4585, "in the Wizard's Tower south of Draynor.")
}
@@ -1,68 +0,0 @@
package core.game.content.activity.gnomecooking
import core.tools.Items
import core.game.node.item.Item
import core.game.node.item.WeightedChanceItem
import core.tools.RandomFunction
object GnomeTipper {
private val easyTips = arrayListOf(
WeightedChanceItem(995,50,100,30),
WeightedChanceItem(995,23,76,50),
WeightedChanceItem(995,10,250,20)
)
private val hardTips = arrayListOf(
//Uniques Weight = 18
WeightedChanceItem(Items.GNOME_GOGGLES_9472,1,2),
WeightedChanceItem(Items.GNOME_SCARF_9470,1,2),
WeightedChanceItem(Items.GRAND_SEED_POD_9469,5,7),
WeightedChanceItem(Items.MINT_CAKE_9475,1,4),
WeightedChanceItem(Items.GNOMEBALL_751,1,4),
//Herbs Weight = 20
WeightedChanceItem(Items.CLEAN_TOADFLAX_2998,3,10),
WeightedChanceItem(Items.CLEAN_SNAPDRAGON_3000,1,10),
//Uncut Gems Weight = 46
WeightedChanceItem(Items.RED_TOPAZ_1613,1,8),
WeightedChanceItem(Items.DIAMOND_1601,1,7),
WeightedChanceItem(Items.UNCUT_EMERALD_1621,3,5,7),
WeightedChanceItem(Items.UNCUT_JADE_1627,2,3,7),
WeightedChanceItem(Items.UNCUT_SAPPHIRE_1623,6,10,8),
WeightedChanceItem(Items.UNCUT_RUBY_1619,2,3,7),
WeightedChanceItem(Items.UNCUT_OPAL_1625,1,10),
//Runes Weight = 25
WeightedChanceItem(Items.COSMIC_RUNE_564,11,5),
WeightedChanceItem(Items.NATURE_RUNE_561,10,15,5),
WeightedChanceItem(Items.LAW_RUNE_563,10,5),
WeightedChanceItem(Items.DEATH_RUNE_560,11,5),
WeightedChanceItem(Items.SOUL_RUNE_566,9,5),
//Untipped crossbow bolts Weight = 9
WeightedChanceItem(Items.MITHRIL_BOLTS_UNF_9379,5,10,3),
WeightedChanceItem(Items.ADAMANT_BOLTSUNF_9380,3,5,3),
WeightedChanceItem(Items.RUNITE_BOLTS_UNF_9381,1,3,3),
//Other tips
WeightedChanceItem(Items.LOOP_HALF_OF_A_KEY_987,1,9),
WeightedChanceItem(Items.TOOTH_HALF_OF_A_KEY_985,1,9),
WeightedChanceItem(Items.PURE_ESSENCE_7937,97,3),
WeightedChanceItem(Items.BIRDS_NEST_5072,1,2),
WeightedChanceItem(Items.YEW_SEED_5315,1,6),
WeightedChanceItem(Items.CALQUAT_TREE_SEED_5290,1,6)
)
enum class LEVEL {
EASY,
HARD
}
@JvmStatic
fun getTip(level: LEVEL): Item {
return when(level){
LEVEL.EASY -> RandomFunction.rollWeightedChanceTable(easyTips)
LEVEL.HARD -> RandomFunction.rollWeightedChanceTable(hardTips)
}
}
}
@@ -1,66 +0,0 @@
package core.game.content.activity.gnomecooking.battas
import core.tools.Items
import core.game.interaction.NodeUsageEvent
import core.game.interaction.UseWithHandler
import core.game.node.entity.player.Player
import core.game.node.item.Item
import core.game.system.task.Pulse
import core.game.world.GameWorld
import core.game.world.update.flag.context.Animation
import core.plugin.Initializable
import core.plugin.Plugin
import core.game.node.entity.skill.Skills
/**
* Handles cook options for battas
* @author Ceikry
*/
@Initializable
class GnomeBattaCooker : UseWithHandler(Items.RAW_BATTA_2250,9478,9480,9482,9483,9485) {
override fun newInstance(arg: Any?): Plugin<Any> {
addHandler(17131, OBJECT_TYPE,this)
addHandler(2728, OBJECT_TYPE,this)
return this
}
override fun handle(event: NodeUsageEvent?): Boolean {
event ?: return false
val player = event.player
val used = event.used
val product = when(used.id){
Items.RAW_BATTA_2250 -> Item(Items.HALF_BAKED_BATTA_2249)
9478 -> Item(9479)
9480 -> Item(9481)
9483 -> Item(9484)
9485 -> Item(9486)
9482 -> Item(2255)
else -> Item(0)
}
if(product.id == 0) return false
cook(player,used.asItem(),product)
return true
}
fun cook(player: Player, raw: Item, product: Item){
GameWorld.Pulser.submit(object : Pulse(){
var counter = 0
override fun pulse(): Boolean {
when(counter++){
0 -> player.lock().also { player.animator.animate(Animation(883)) }
2 -> {
if(player.inventory.containsItem(raw)) {
player.inventory.remove(raw)
player.inventory.add(product)
if(product.id == 2255) player.skills.addExperience(Skills.COOKING,82.0)
else player.skills.addExperience(Skills.COOKING,40.0)
}
player.unlock()
return true
}
}
return false
}
})
}
}
@@ -1,36 +0,0 @@
package core.game.content.activity.gnomecooking.battas
import core.tools.Items
import core.game.interaction.NodeUsageEvent
import core.game.interaction.UseWithHandler
import core.game.node.item.Item
import core.plugin.Initializable
import core.plugin.Plugin
private const val GIANNE_DOUGH = 2171
private const val BATTA_MOULD = 2164
private const val RAW_CRUNCHIES = 2202
/**
* Fills gnome batta dishes
* @author Ceikry
*/
@Initializable
class GnomeBattaDishFiller : UseWithHandler(GIANNE_DOUGH) {
override fun newInstance(arg: Any?): Plugin<Any> {
addHandler(BATTA_MOULD, ITEM_TYPE,this)
return this
}
override fun handle(event: NodeUsageEvent?): Boolean {
event ?: return false
val player = event.player
val used = event.used
val with = event.usedWith
player.inventory.remove(used.asItem())
player.inventory.remove(with.asItem())
player.inventory.add(Item(Items.RAW_BATTA_2250))
return true
}
}
@@ -1,51 +0,0 @@
package core.game.content.activity.gnomecooking.battas
import core.tools.Items
import core.game.interaction.NodeUsageEvent
import core.game.interaction.UseWithHandler
import core.game.node.item.Item
import core.plugin.Initializable
import core.plugin.Plugin
import core.game.node.entity.skill.Skills
/**
* Handles garnishing of battas
* @author Ceikry
*/
@Initializable
class GnomeBattaGarnisher : UseWithHandler(9479,9481,9484,9486) {
override fun newInstance(arg: Any?): Plugin<Any> {
addHandler(Items.EQUA_LEAVES_2128, ITEM_TYPE,this)
addHandler(Items.GNOME_SPICE_2169, ITEM_TYPE,this)
return this
}
override fun handle(event: NodeUsageEvent?): Boolean {
event ?: return false
val player = event.player
val used = event.used.asItem()
val with = event.usedWith.asItem()
var product = -1
when(with.id){
Items.EQUA_LEAVES_2128 -> {
when(used.id){
9486 -> product = Items.WORM_BATTA_2253
9484 -> product = Items.VEGETABLE_BATTA_2281
9479 -> product = Items.CHEESE_PLUSTOM_BATTA_2259
}
}
Items.GNOME_SPICE_2169 -> {
when(used.id){
9481 -> product = Items.FRUIT_BATTA_2277
}
}
}
if(product == -1) return false
player.inventory.remove(used)
player.inventory.remove(with)
player.inventory.add(Item(product))
player.skills.addExperience(Skills.COOKING,88.0)
return true
}
}
@@ -1,97 +0,0 @@
package core.game.content.activity.gnomecooking.battas
import core.game.component.Component
import core.game.component.ComponentDefinition
import core.game.component.ComponentPlugin
import core.tools.Items
import core.game.node.entity.player.Player
import core.game.node.item.Item
import core.plugin.Initializable
import core.plugin.Plugin
import core.game.node.entity.skill.Skills
private const val WORM_BATTA = 2219
private const val TOAD_BATTA = 2221
private const val CHEESE_TOM_BATTA = 2223
private const val FRUIT_BATTA = 2225
private const val VEG_BATTA = 2227
/**
* Handles the gnome batta interface
* @author Ceikry
*/
@Initializable
class GnomeBattaInterface : ComponentPlugin() {
override fun open(player: Player?, component: Component?) {
component ?: return
player ?: return
super.open(player, component)
player.packetDispatch.sendItemOnInterface(FRUIT_BATTA,component.id,component.id,3)
player.packetDispatch.sendItemOnInterface(TOAD_BATTA,component.id,component.id,14)
player.packetDispatch.sendItemOnInterface(WORM_BATTA,component.id,component.id,25)
player.packetDispatch.sendItemOnInterface(VEG_BATTA,component.id,component.id,34)
player.packetDispatch.sendItemOnInterface(CHEESE_TOM_BATTA,component.id,component.id,47)
}
override fun handle(player: Player?, component: Component?, opcode: Int, button: Int, slot: Int, itemId: Int): Boolean {
player ?: return false
component ?: return false
when(button){
3 -> attemptMake(CookedProduct.HALF_MADE_FR,player)
14 -> attemptMake(CookedProduct.HALF_MADE_TO,player)
25 -> attemptMake(CookedProduct.HALF_MADE_WO,player)
34 -> attemptMake(CookedProduct.HALF_MADE_VE,player)
47 -> attemptMake(CookedProduct.HALF_MADE_CT,player)
}
return true
}
private fun attemptMake(batta: CookedProduct, player: Player){
if(!player.inventory.containsItem(Item(Items.GNOME_SPICE_2169)) && (batta == CookedProduct.HALF_MADE_TO || batta == CookedProduct.HALF_MADE_WO) ){
player.dialogueInterpreter.sendDialogue("You need gnome spices for this.")
return
}
if(player.skills.getLevel(Skills.COOKING) < batta.levelReq){
player.dialogueInterpreter.sendDialogue("You don't have the needed level to make this.")
return
}
var hasAll = true
for(item in batta.requiredItems){
if(!player.inventory.containsItem(item)){
hasAll = false
break
}
}
if(!hasAll){
player.dialogueInterpreter.sendDialogue("You don't have all the ingredients needed for this.")
return
}
player.inventory.remove(*batta.requiredItems)
player.inventory.remove(Item(Items.HALF_BAKED_BATTA_2249))
player.inventory.add(Item(batta.product))
player.skills.addExperience(Skills.COOKING,batta.experience)
player.interfaceManager.close()
}
internal enum class CookedProduct(val product: Int,val levelReq: Int, val experience: Double, val requiredItems: Array<Item>){
HALF_MADE_CT(9478,29,40.0, arrayOf(Item(Items.TOMATO_1982), Item(Items.CHEESE_1985))),
HALF_MADE_FR(9480,25,40.0, arrayOf(Item(Items.EQUA_LEAVES_2128,4), Item(Items.LIME_CHUNKS_2122), Item(Items.ORANGE_CHUNKS_2110), Item(Items.PINEAPPLE_CHUNKS_2116))),
HALF_MADE_TO(9482,26,40.0, arrayOf(Item(Items.EQUA_LEAVES_2128), Item(Items.CHEESE_1985), Item(Items.TOADS_LEGS_2152))),
HALF_MADE_VE(9483,28,40.0, arrayOf(Item(Items.TOMATO_1982,2), Item(Items.CHEESE_1985), Item(Items.DWELLBERRIES_2126), Item(Items.ONION_1957), Item(Items.CABBAGE_1965))),
HALF_MADE_WO(9485,27,40.0, arrayOf(Item(Items.KING_WORM_2162), Item(Items.CHEESE_1985)))
}
override fun newInstance(arg: Any?): Plugin<Any> {
ComponentDefinition.put(434,this)
return this
}
}
@@ -1,30 +0,0 @@
package core.game.content.activity.gnomecooking.battas
import core.cache.def.impl.ItemDefinition
import core.game.component.Component
import core.tools.Items
import core.game.interaction.OptionHandler
import core.game.node.Node
import core.game.node.entity.player.Player
import core.plugin.Initializable
import core.plugin.Plugin
import core.tools.Components
/**
* Handles the prepare option for gnome battas
* @author Ceikry
*/
@Initializable
class GnomeBattaPrepareHandler : OptionHandler() {
override fun newInstance(arg: Any?): Plugin<Any> {
ItemDefinition.forId(Items.HALF_BAKED_BATTA_2249).handlers["option:prepare"] = this
return this
}
override fun handle(player: Player?, node: Node?, option: String?): Boolean {
player ?: return false
player.interfaceManager.open(Component(Components.gnome_battas_434))
return true
}
}
@@ -1,64 +0,0 @@
package core.game.content.activity.gnomecooking.bowls
import core.tools.Items
import core.game.interaction.NodeUsageEvent
import core.game.interaction.UseWithHandler
import core.game.node.entity.player.Player
import core.game.node.item.Item
import core.game.system.task.Pulse
import core.game.world.GameWorld
import core.game.world.update.flag.context.Animation
import core.plugin.Initializable
import core.plugin.Plugin
import core.game.node.entity.skill.Skills
@Initializable
class GnomeBowlCooker : UseWithHandler(Items.RAW_GNOMEBOWL_2178,9558,9559,9561,9563) {
override fun newInstance(arg: Any?): Plugin<Any> {
addHandler(17131, OBJECT_TYPE,this)
addHandler(2728, OBJECT_TYPE,this)
return this
}
override fun handle(event: NodeUsageEvent?): Boolean {
event ?: return false
val player = event.player
val used = event.used
val product = when(used.id){
Items.RAW_GNOMEBOWL_2178 -> Item(Items.HALF_BAKED_BOWL_2177)
9558 -> Item(9560)
9559 -> Item(Items.TANGLED_TOADS_LEGS_2187)
9561 -> Item(9562)
9563 -> Item(9564)
else -> Item(0)
}
if(product.id == 0) return false
cook(player,used.asItem(),product)
return true
}
fun cook(player: Player, raw: Item, product: Item){
GameWorld.Pulser.submit(object : Pulse(){
var counter = 0
override fun pulse(): Boolean {
when(counter++){
0 -> player.lock().also { player.animator.animate(Animation(883)) }
2 -> {
if(player.inventory.containsItem(raw)) {
if(product.id > 2180){
player.inventory.add(Item(Items.GNOMEBOWL_MOULD_2166))
}
player.inventory.remove(raw)
player.inventory.add(product)
player.skills.addExperience(Skills.COOKING,30.0)
}
player.unlock()
return true
}
}
return false
}
})
}
}
@@ -1,59 +0,0 @@
package core.game.content.activity.gnomecooking.bowls
import core.game.interaction.UseWithHandler
import core.tools.Items
import core.game.interaction.NodeUsageEvent
import core.game.node.item.Item
import core.plugin.Initializable
import core.plugin.Plugin
/**
* Handles garnishing of gnomebowls
* @author Ceikry
*/
@Initializable
class GnomeBowlGarnisher : UseWithHandler(9560,9562,9564) {
override fun newInstance(arg: Any?): Plugin<Any> {
addHandler(Items.EQUA_LEAVES_2128, ITEM_TYPE,this)
addHandler(Items.POT_OF_CREAM_2130, ITEM_TYPE,this)
addHandler(Items.CHOCOLATE_DUST_1975, ITEM_TYPE,this)
return this
}
override fun handle(event: NodeUsageEvent?): Boolean {
event ?: return false
val player = event.player
val used = event.used.asItem()
val with = event.usedWith.asItem()
var product = -1
when(with.id){
Items.EQUA_LEAVES_2128 -> {
when(used.id){
9562 -> product = Items.VEG_BALL_2195
9564 -> product = Items.WORM_HOLE_2191
}
}
Items.POT_OF_CREAM_2130,Items.CHOCOLATE_DUST_1975 -> {
when(used.id){
9560 -> product = Items.CHOCOLATE_BOMB_2185
}
}
}
if(product == Items.CHOCOLATE_BOMB_2185){
val reqCream = Item(Items.POT_OF_CREAM_2130,2)
val reqChoc = Item(Items.CHOCOLATE_DUST_1975)
if(!player.inventory.containsItem(reqChoc) || !player.inventory.containsItem(reqCream)){
player.dialogueInterpreter.sendDialogue("You don't have enough ingredients to finish that.")
return true
}
player.inventory.remove(reqCream)
player.inventory.remove(reqChoc)
}
if(product == -1) return false
player.inventory.remove(used)
player.inventory.remove(with)
player.inventory.add(Item(product))
return true
}
}
@@ -1,71 +0,0 @@
package core.game.content.activity.gnomecooking.bowls
import core.game.component.Component
import core.game.component.ComponentDefinition
import core.game.component.ComponentPlugin
import core.tools.Items
import core.game.node.entity.player.Player
import core.game.node.item.Item
import core.plugin.Initializable
import core.plugin.Plugin
import core.game.node.entity.skill.Skills
@Initializable
class GnomeBowlInterface : ComponentPlugin() {
override fun handle(player: Player?, component: Component?, opcode: Int, button: Int, slot: Int, itemId: Int): Boolean {
player ?: return false
component ?: return false
when(button){
3 -> attemptMake(PreparedProduct.HALF_MADE_WOR_HO,player)
12 -> attemptMake(PreparedProduct.HALF_MADE_VEG_BA,player)
21 -> attemptMake(PreparedProduct.HALF_MADE_TAN_TO,player)
34 -> attemptMake(PreparedProduct.HALF_MADE_CHOC_B,player)
}
return true
}
private fun attemptMake(bowl: PreparedProduct, player: Player){
if(!player.inventory.containsItem(Item(Items.GNOME_SPICE_2169)) && (bowl != PreparedProduct.HALF_MADE_CHOC_B) ){
player.dialogueInterpreter.sendDialogue("You need gnome spices for this.")
return
}
if(player.skills.getLevel(Skills.COOKING) < bowl.levelReq){
player.dialogueInterpreter.sendDialogue("You don't have the needed level to make this.")
return
}
var hasAll = true
for(item in bowl.requiredItems){
if(!player.inventory.containsItem(item)){
hasAll = false
break
}
}
if(!hasAll){
player.dialogueInterpreter.sendDialogue("You don't have all the ingredients needed for this.")
return
}
player.inventory.remove(*bowl.requiredItems)
player.inventory.remove(Item(Items.HALF_BAKED_BOWL_2177))
player.inventory.add(Item(bowl.product))
player.interfaceManager.close()
}
internal enum class PreparedProduct(val product: Int,val levelReq: Int, val requiredItems: Array<Item>){
HALF_MADE_CHOC_B(9558,42, arrayOf(Item(Items.CHOCOLATE_BAR_1973,4),Item(Items.EQUA_LEAVES_2128))),
HALF_MADE_TAN_TO(9559,40, arrayOf(Item(Items.TOADS_LEGS_2152,4),Item(Items.CHEESE_1985,2),Item(Items.DWELLBERRIES_2126),Item(Items.EQUA_LEAVES_2128,2))),
HALF_MADE_VEG_BA(9561,35, arrayOf(Item(Items.POTATO_1942,2),Item(Items.ONION_1957,2))),
HALF_MADE_WOR_HO(9563,30, arrayOf(Item(Items.KING_WORM_2162,4),Item(Items.ONION_1957,2)))
}
override fun newInstance(arg: Any?): Plugin<Any> {
ComponentDefinition.put(435,this)
return this
}
}
@@ -1,26 +0,0 @@
package core.game.content.activity.gnomecooking.bowls
import core.cache.def.impl.ItemDefinition
import core.game.component.Component
import core.tools.Items
import core.game.interaction.OptionHandler
import core.game.node.Node
import core.game.node.entity.player.Player
import core.plugin.Initializable
import core.plugin.Plugin
import core.tools.Components
@Initializable
class GnomeBowlPrepareHandler : OptionHandler() {
override fun newInstance(arg: Any?): Plugin<Any> {
ItemDefinition.forId(Items.HALF_BAKED_BOWL_2177).handlers["option:prepare"] = this
return this
}
override fun handle(player: Player?, node: Node?, option: String?): Boolean {
player ?: return false
player.interfaceManager.open(Component(Components.gnome_bowls_435))
return true
}
}
@@ -1,31 +0,0 @@
package core.game.content.activity.gnomecooking.bowls
import core.game.interaction.NodeUsageEvent
import core.game.interaction.UseWithHandler
import core.game.node.item.Item
import core.plugin.Initializable
import core.plugin.Plugin
import core.tools.Items
private const val GNOME_BOWL_MOLD = 2166
private const val GIANNE_DOUGH = 2171
@Initializable
class GnomebowlMouldFiller : UseWithHandler(GIANNE_DOUGH) {
override fun newInstance(arg: Any?): Plugin<Any> {
addHandler(GNOME_BOWL_MOLD, ITEM_TYPE,this)
return this
}
override fun handle(event: NodeUsageEvent?): Boolean {
event ?: return false
val player = event.player
val used = event.used.asItem()
val with = event.usedWith.asItem()
player.inventory.remove(used)
player.inventory.remove(with)
player.inventory.add(Item(Items.RAW_GNOMEBOWL_2178))
return true
}
}
@@ -1,61 +0,0 @@
package core.game.content.activity.gnomecooking.cocktails
import core.game.interaction.NodeUsageEvent
import core.game.interaction.UseWithHandler
import core.game.node.entity.player.Player
import core.game.node.item.Item
import core.game.system.task.Pulse
import core.game.world.GameWorld
import core.game.world.update.flag.context.Animation
import core.plugin.Initializable
import core.plugin.Plugin
private const val UNCOOKED_CHOC_SAT = 9572
private const val UNCOOKED_DRUN_DRA = 9576
/**
* Handles the cooking of certain cocktail products
* @author Ceikry
*/
@Initializable
class CocktailCooker : UseWithHandler(UNCOOKED_CHOC_SAT, UNCOOKED_DRUN_DRA) {
override fun newInstance(arg: Any?): Plugin<Any> {
addHandler(17131, OBJECT_TYPE,this)
addHandler(2728, OBJECT_TYPE,this)
return this
}
override fun handle(event: NodeUsageEvent?): Boolean {
when(event?.used?.id){
UNCOOKED_CHOC_SAT -> cook(CookedDrinks.COOKED_CHOC_SAT,event.player,event.usedItem)
UNCOOKED_DRUN_DRA -> cook(CookedDrinks.COOKED_DRUN_DRA,event.player,event.usedItem)
}
return true
}
private fun cook(drink: CookedDrinks, player: Player, raw: Item){
GameWorld.Pulser.submit(object : Pulse(){
var counter = 0
override fun pulse(): Boolean {
when(counter++){
0 -> player.lock().also { player.animator.animate(Animation(883)) }
2 -> {
if(player.inventory.containsItem(raw)) {
player.inventory.remove(raw)
player.inventory.add(Item(drink.product))
}
player.unlock()
return true
}
}
return false
}
})
}
internal enum class CookedDrinks(val product: Int){
COOKED_CHOC_SAT(9573),
COOKED_DRUN_DRA(2092)
}
}
@@ -1,61 +0,0 @@
package core.game.content.activity.gnomecooking.cocktails
import core.cache.def.impl.ItemDefinition
import core.tools.Items
import core.game.interaction.OptionHandler
import core.game.node.Node
import core.game.node.entity.player.Player
import core.game.node.item.Item
import core.plugin.Initializable
import core.plugin.Plugin
private const val UNF_CHOC_SAT = 9573
private const val UNF_DRUN_DRA = 9575
/**
* Handles adding the final ingredients to a couple cocktails
* @author Ceikry
*/
@Initializable
class CocktailFinisher : OptionHandler() {
override fun newInstance(arg: Any?): Plugin<Any> {
ItemDefinition.forId(UNF_CHOC_SAT).handlers["option:add-ingreds"] = this
ItemDefinition.forId(UNF_DRUN_DRA).handlers["option:add-ingreds"] = this
return this
}
override fun handle(player: Player?, node: Node?, option: String?): Boolean {
player ?: return false
node ?: return false
when(node.id){
UNF_CHOC_SAT -> attemptMake(FinishedDrinks.FIN_CHOC_SAT,player,node)
UNF_DRUN_DRA -> attemptMake(FinishedDrinks.FIN_DRUN_DRA,player,node)
}
return true
}
private fun attemptMake(drink: FinishedDrinks, player: Player, node: Node){
var hasAll = true
for(item in drink.requiredItems){
if(!player.inventory.containsItem(item)){
hasAll = false
break
}
}
if(!hasAll){
player.dialogueInterpreter.sendDialogue("You don't have the ingredients for this.")
return
}
player.inventory.remove(*drink.requiredItems)
player.inventory.remove(node.asItem())
player.inventory.add(Item(drink.product))
}
internal enum class FinishedDrinks(val product: Int, val requiredItems: Array<Item>){
FIN_CHOC_SAT(2074, arrayOf(Item(Items.CHOCOLATE_DUST_1975),Item(Items.POT_OF_CREAM_2130))),
FIN_DRUN_DRA(9576, arrayOf(Item(Items.PINEAPPLE_CHUNKS_2116),Item(Items.POT_OF_CREAM_2130)))
}
}
@@ -1,30 +0,0 @@
package core.game.content.activity.gnomecooking.cocktails
import core.cache.def.impl.ItemDefinition
import core.game.component.Component
import core.game.interaction.OptionHandler
import core.game.node.Node
import core.game.node.entity.player.Player
import core.plugin.Initializable
import core.plugin.Plugin
import core.tools.Components
/**
* Handles the mix-cocktail option for the cocktail shaker
* @author Ceikry
*/
@Initializable
class CocktailShakerHandler : OptionHandler() {
override fun newInstance(arg: Any?): Plugin<Any> {
ItemDefinition.forId(2025).handlers["option:mix-cocktail"] = this
return this
}
override fun handle(player: Player?, node: Node?, option: String?): Boolean {
player ?: return false
node ?: return false
player.interfaceManager.open(Component(Components.gnome_cocktails_436)) //Gnome cocktail interface
return true
}
}
@@ -1,98 +0,0 @@
package core.game.content.activity.gnomecooking.cocktails
import core.game.component.Component
import core.game.component.ComponentDefinition
import core.game.component.ComponentPlugin
import core.game.node.entity.player.Player
import core.game.node.item.Item
import core.plugin.Initializable
import core.plugin.Plugin
import core.tools.Items
import core.game.node.entity.skill.Skills
private const val WIZARD_BLIZZARD = 2054
private const val SHORT_GREEN_GUY = 2080
private const val FRUIT_BLAST = 2084
private const val PINEAPPLE_PUNCH = 2048
private const val DRUNK_DRAGON = 2092
private const val CHOC_SATURDAY = 2074
private const val BLURBERRY_SPECIAL = 2064
/**
* Handles the gnome cocktail interface
* @author Ceikry
*/
@Initializable
class GnomeCocktailInterface : ComponentPlugin() {
override fun open(player: Player?, component: Component?) {
player ?: return
component ?: return
super.open(player, component)
player.packetDispatch.sendItemOnInterface(WIZARD_BLIZZARD,1,component.id,3)
player.packetDispatch.sendItemOnInterface(SHORT_GREEN_GUY,1,component.id,16)
player.packetDispatch.sendItemOnInterface(FRUIT_BLAST,1,component.id,23)
player.packetDispatch.sendItemOnInterface(PINEAPPLE_PUNCH,1,component.id,32)
player.packetDispatch.sendItemOnInterface(DRUNK_DRAGON,1,component.id,41)
player.packetDispatch.sendItemOnInterface(CHOC_SATURDAY,1,component.id,50)
player.packetDispatch.sendItemOnInterface(BLURBERRY_SPECIAL,1,component.id,61)
}
override fun handle(player: Player?, component: Component?, opcode: Int, button: Int, slot: Int, itemId: Int): Boolean {
player ?: return false
when(button){
3 -> attemptMake(FruitCocktail.WIZARD_BLIZZARD,player)
16 -> attemptMake(FruitCocktail.SHORT_GREEN_GUY, player)
23 -> attemptMake(FruitCocktail.FRUIT_BLAST, player)
32 -> attemptMake(FruitCocktail.PINEAPPLE_PUNCH,player)
41 -> attemptMake(FruitCocktail.DRUNK_DRAGON,player)
50 -> attemptMake(FruitCocktail.CHOC_SATURDAY,player)
61 -> attemptMake(FruitCocktail.BLURBERRY_SPEC,player)
}
return true
}
private fun attemptMake(cocktail: FruitCocktail, player: Player){
var hasAll = true
val cookingLevel = player.skills.getLevel(Skills.COOKING)
if(cookingLevel < cocktail.levelReq){
player.dialogueInterpreter.sendDialogue("You don't have the necessary level to make that.")
return
}
for(ingredient in cocktail.requiredItems){
if(!player.inventory.containsItem(ingredient)){
hasAll = false
break
}
}
if(!hasAll){
player.dialogueInterpreter.sendDialogue("You don't have the ingredients to make that.")
return
}
player.inventory.remove(*cocktail.requiredItems)
player.inventory.remove(Item(Items.COCKTAIL_SHAKER_2025))
player.inventory.add(Item(cocktail.product))
player.skills.addExperience(Skills.COOKING,cocktail.experience)
player.interfaceManager.close()
}
override fun newInstance(arg: Any?): Plugin<Any> {
ComponentDefinition.put(436,this)
return this
}
internal enum class FruitCocktail(val levelReq: Int, val experience: Double, val product: Int, val requiredItems: Array<Item>){
FRUIT_BLAST(6,50.0,9568, arrayOf(Item(Items.PINEAPPLE_2114),Item(Items.LEMON_2102),Item(Items.ORANGE_2108))),
PINEAPPLE_PUNCH(8,70.0,9569, arrayOf(Item(Items.PINEAPPLE_2114,2),Item(Items.LEMON_2102),Item(Items.ORANGE_2108))),
WIZARD_BLIZZARD(18,110.0, 9566, arrayOf(Item(Items.VODKA_2015,2),Item(Items.GIN_2019),Item(Items.LIME_2120),Item(Items.LEMON_2102),Item(Items.ORANGE_2108))),
SHORT_GREEN_GUY(20,120.0,9567, arrayOf(Item(Items.VODKA_2015),Item(Items.LIME_2120,3))),
DRUNK_DRAGON(32,160.0,9574, arrayOf(Item(Items.VODKA_2015),Item(Items.GIN_2019),Item(Items.DWELLBERRIES_2126))),
CHOC_SATURDAY(33,170.0,9571, arrayOf(Item(Items.WHISKY_2017),Item(Items.CHOCOLATE_BAR_1973),Item(Items.EQUA_LEAVES_2128),Item(Items.BUCKET_OF_MILK_1927))),
BLURBERRY_SPEC(37,180.0,9570, arrayOf(Item(Items.VODKA_2015),Item(Items.BRANDY_2021),Item(Items.GIN_2019),Item(Items.LEMON_2102,2),Item(Items.ORANGE_2108)))
}
}
@@ -1,86 +0,0 @@
package core.game.content.activity.gnomecooking.cocktails
import core.cache.def.impl.ItemDefinition
import core.tools.Items
import core.game.interaction.OptionHandler
import core.game.node.Node
import core.game.node.entity.player.Player
import core.game.node.item.Item
import core.plugin.Initializable
import core.plugin.Plugin
import core.game.node.entity.skill.Skills
private const val WIZ_BLIZ_MIX = 9566
private const val SGG_MIX = 9567
private const val F_BLAST_MIX = 9568
private const val P_PUNCH_MIX = 9569
private const val BLU_SPEC_MIX = 9570
private const val CHOC_SAT_MIX = 9571
private const val DRUNK_DRAG_MIX = 9574
private val mixers = arrayOf(WIZ_BLIZ_MIX, SGG_MIX, F_BLAST_MIX, P_PUNCH_MIX, BLU_SPEC_MIX, CHOC_SAT_MIX, DRUNK_DRAG_MIX)
/**
* Handles the pouring of mixed drinks into cocktail glasses
* @author Ceikry
*/
@Initializable
class PourMixerPlugin : OptionHandler() {
override fun newInstance(arg: Any?): Plugin<Any> {
for(mixer in mixers){
ItemDefinition.forId(mixer).handlers["option:pour"] = this
}
return this
}
override fun handle(player: Player?, node: Node?, option: String?): Boolean {
player ?: return false
node ?: return false
when(node.id){
WIZ_BLIZ_MIX -> attemptMake(PouredDrink.WIZ_BLIZZ,player,node)
SGG_MIX -> attemptMake(PouredDrink.SHORT_G_G,player,node)
F_BLAST_MIX -> attemptMake(PouredDrink.FRUIT_BLAST,player,node)
P_PUNCH_MIX -> attemptMake(PouredDrink.PINE_PUNCH,player,node)
BLU_SPEC_MIX -> attemptMake(PouredDrink.BLUR_SPEC, player,node)
CHOC_SAT_MIX -> attemptMake(PouredDrink.CHOC_SAT,player,node)
DRUNK_DRAG_MIX -> attemptMake(PouredDrink.DRUNK_DRAG,player,node)
}
return true
}
private fun attemptMake(drink: PouredDrink, player: Player, node: Node){
if(!player.inventory.containsItem(Item(Items.COCKTAIL_GLASS_2026))){
player.dialogueInterpreter.sendDialogue("You need a glass to pour this into.")
return
}
var hasAll = true
for(ingredient in drink.requiredItems){
if(!player.inventory.containsItem(ingredient)){
hasAll = false
}
}
if(!hasAll){
player.dialogueInterpreter.sendDialogue("You don't have the garnishes for this.")
return
}
player.inventory.remove(*drink.requiredItems)
player.inventory.remove(node.asItem())
player.inventory.remove(Item(Items.COCKTAIL_GLASS_2026))
player.inventory.add(Item(drink.product))
player.inventory.add(Item(Items.COCKTAIL_SHAKER_2025))
player.skills.addExperience(Skills.COOKING,50.0)
}
internal enum class PouredDrink(val product: Int, val requiredItems: Array<Item>){
FRUIT_BLAST(9514, arrayOf(Item(Items.LEMON_SLICES_2106))),
PINE_PUNCH(9512, arrayOf(Item(Items.LIME_CHUNKS_2122),Item(Items.PINEAPPLE_CHUNKS_2116),Item(Items.ORANGE_SLICES_2112))),
WIZ_BLIZZ(9508, arrayOf(Item(Items.PINEAPPLE_CHUNKS_2116),Item(Items.LIME_SLICES_2124))),
SHORT_G_G(9510, arrayOf(Item(Items.LIME_SLICES_2124),Item(Items.EQUA_LEAVES_2128))),
DRUNK_DRAG(9575, arrayOf()),
CHOC_SAT(9572, arrayOf()),
BLUR_SPEC(9520, arrayOf(Item(Items.LEMON_CHUNKS_2104),Item(Items.ORANGE_CHUNKS_2110),Item(Items.EQUA_LEAVES_2128),Item(Items.LIME_SLICES_2124))),
}
}
@@ -1,71 +0,0 @@
package core.game.content.activity.gnomecooking.crunchies
import core.game.interaction.NodeUsageEvent
import core.game.interaction.UseWithHandler
import core.game.node.entity.player.Player
import core.game.node.item.Item
import core.game.system.task.Pulse
import core.game.world.GameWorld
import core.game.world.update.flag.context.Animation
import core.plugin.Initializable
import core.plugin.Plugin
import core.game.node.entity.skill.Skills
private const val UNFINISHED_CRUNCHY_CHOC = 9578
private const val UNFINISHED_CRUNCHY_SPICY = 9580
private const val UNFINISHED_CRUNCHY_TOAD = 9582
private const val UNFINISHED_CRUNCHY_WORM = 9584
/**
* handles cooking gnome crunchies, don't wanna use standard
* cooking stuff because no experience and no burn chance
* @author Ceikry
*/
@Initializable
class GnomeCrunchyCooker : UseWithHandler(9577,9579,9581,9583, 2202){
override fun newInstance(arg: Any?): Plugin<Any> {
addHandler(17131, OBJECT_TYPE,this)
addHandler(2728, OBJECT_TYPE,this)
return this
}
override fun handle(event: NodeUsageEvent?): Boolean {
event ?: return false
val used = event.used.asItem()
val with = event.usedWith
val player = event.player
when(used.id){
9577 -> cook(UNFINISHED_CRUNCHY_CHOC,used,player)
9579 -> cook(UNFINISHED_CRUNCHY_SPICY,used,player)
9581 -> cook(UNFINISHED_CRUNCHY_TOAD,used,player)
9583 -> cook(UNFINISHED_CRUNCHY_WORM,used,player)
2202 -> cook(2201,used,player)
}
return true
}
private fun cook(product: Int, raw: Item, player: Player){
GameWorld.Pulser.submit(object : Pulse(){
var counter = 0
override fun pulse(): Boolean {
when(counter++){
0 -> player.lock().also { player.animator.animate(Animation(883)) }
2 -> {
if(player.inventory.containsItem(raw)) {
player.inventory.remove(raw)
player.inventory.add(Item(product))
if(raw.id != 2202) player.inventory.add(Item(2165))
}
if(raw.id == 2202){
player.skills.addExperience(Skills.COOKING,30.0)
}
player.unlock()
return true
}
}
return false
}
})
}
}
@@ -1,67 +0,0 @@
package core.game.content.activity.gnomecooking.crunchies
import core.tools.Items
import core.game.interaction.NodeUsageEvent
import core.game.interaction.UseWithHandler
import core.game.node.item.Item
import core.plugin.Initializable
import core.plugin.Plugin
import core.game.node.entity.skill.Skills
/**
* Handles garnishing gnome crunchies
* @author Ceikry
*/
@Initializable
class GnomeCrunchyGarnisher : UseWithHandler(9578,9580,9582,9584) {
override fun newInstance(arg: Any?): Plugin<Any> {
addHandler(Items.CHOCOLATE_DUST_1975, ITEM_TYPE,this)
addHandler(Items.GNOME_SPICE_2169, ITEM_TYPE, this)
addHandler(Items.EQUA_LEAVES_2128, ITEM_TYPE, this)
return this
}
override fun handle(event: NodeUsageEvent?): Boolean {
event ?: return false
val player = event.player
val used = event.used.asItem()
val with = event.usedWith.asItem()
val product = when(with.id){
Items.CHOCOLATE_DUST_1975 -> {
when(used.id){
9578 -> Items.CHOCCHIP_CRUNCHIES_2209
else -> -1
}
}
Items.GNOME_SPICE_2169 -> {
when(used.id){
9584 -> Items.WORM_CRUNCHIES_2205
9580 -> Items.SPICY_CRUNCHIES_2213
else -> -1
}
}
Items.EQUA_LEAVES_2128 -> {
when(used.id){
9582 -> Items.TOAD_CRUNCHIES_2217
else -> -1
}
}
else -> -1
}
if(product == -1) return false
player.inventory.remove(used)
if(with.id != Items.GNOME_SPICE_2169)
player.inventory.remove(with)
player.inventory.add(Item(product))
player.skills.addExperience(Skills.COOKING,64.0)
return true
}
}
@@ -1,91 +0,0 @@
package core.game.content.activity.gnomecooking.crunchies
import core.game.component.Component
import core.game.component.ComponentDefinition
import core.game.component.ComponentPlugin
import core.game.node.entity.player.Player
import core.game.node.item.Item
import core.plugin.Initializable
import core.plugin.Plugin
import core.tools.Items
import core.game.node.entity.skill.Skills
private const val TOAD_CRUNCHIES = 9538
private const val SPICE_CRUNCHIES = 9540
private const val CHOC_CHIP_CRUNCHIES = 9544
private const val WORM_CRUNCHIES = 9542
private const val HALF_BAKED_CRUNCHY = 2201
/**
* Handles the gnome crunchy interface
* @author Ceikry
*/
@Initializable
class GnomeCrunchyInterface : ComponentPlugin() {
override fun handle(player: Player?, component: Component?, opcode: Int, button: Int, slot: Int, itemId: Int): Boolean {
player ?: return false
when(button){
3 -> attemptMake(HalfMadeCrunchy.TOAD,player)
10 -> attemptMake(HalfMadeCrunchy.SPICY,player)
17 -> attemptMake(HalfMadeCrunchy.WORM,player)
26 -> attemptMake(HalfMadeCrunchy.CHOCCHIP,player)
}
return true
}
private fun attemptMake(crunchy: HalfMadeCrunchy, player: Player){
var hasAll = true
if(player.skills.getLevel(Skills.COOKING) < crunchy.reqLevel){
player.dialogueInterpreter.sendDialogue("You don't have the required level to make these.")
return
}
if(!player.inventory.containsItem(Item(Items.GNOME_SPICE_2169))){
player.dialogueInterpreter.sendDialogue("You need some gnome spice to make these.")
return
}
for(item in crunchy.requiredItems){
if(!player.inventory.containsItem(item)){
hasAll = false
break;
}
}
if(!hasAll){
player.dialogueInterpreter.sendDialogue("You don't have the required ingredients to make these.")
return
}
player.inventory.remove(*crunchy.requiredItems)
player.inventory.remove(Item(HALF_BAKED_CRUNCHY))
player.inventory.add(Item(crunchy.product))
player.skills.addExperience(Skills.COOKING,30.0)
player.interfaceManager.close()
}
override fun open(player: Player?, component: Component?) {
player ?: return
component ?: return
super.open(player, component)
player.packetDispatch.sendItemOnInterface(TOAD_CRUNCHIES,1,component.id,3)
player.packetDispatch.sendItemOnInterface(SPICE_CRUNCHIES,1,component.id,10)
player.packetDispatch.sendItemOnInterface(WORM_CRUNCHIES,1,component.id,17)
player.packetDispatch.sendItemOnInterface(CHOC_CHIP_CRUNCHIES,1,component.id,26)
}
override fun newInstance(arg: Any?): Plugin<Any> {
ComponentDefinition.put(437,this)
return this
}
internal enum class HalfMadeCrunchy(val product: Int,val reqLevel: Int, val requiredItems: Array<Item>){
CHOCCHIP(9577, 16, arrayOf(Item(Items.CHOCOLATE_BAR_1973,2))),
SPICY(9579, 12, arrayOf(Item(Items.EQUA_LEAVES_2128,2))),
TOAD(9581, 10, arrayOf(Item(Items.TOADS_LEGS_2152,2))),
WORM(9583, 14, arrayOf(Item(Items.EQUA_LEAVES_2128),Item(Items.KING_WORM_2162,2)))
}
}
@@ -1,30 +0,0 @@
package core.game.content.activity.gnomecooking.crunchies
import core.cache.def.impl.ItemDefinition
import core.game.component.Component
import core.game.interaction.OptionHandler
import core.game.node.Node
import core.game.node.entity.player.Player
import core.plugin.Initializable
import core.plugin.Plugin
import core.tools.Components
private const val HALF_BAKED_CRUNCHY = 2201
private const val CRUNCHY_INTERFACE = Components.gnome_crunchies_437
/**
* Opens the gnome crunchy interface
*/
@Initializable
class GnomeCrunchyPrepareHandler : OptionHandler() {
override fun newInstance(arg: Any?): Plugin<Any> {
ItemDefinition.forId(HALF_BAKED_CRUNCHY).handlers["option:prepare"] = this
return this
}
override fun handle(player: Player?, node: Node?, option: String?): Boolean {
player ?: return false
player.interfaceManager.open(Component(CRUNCHY_INTERFACE))
return true
}
}
@@ -1,32 +0,0 @@
package core.game.content.activity.gnomecooking.crunchies
import core.game.interaction.NodeUsageEvent
import core.game.interaction.UseWithHandler
import core.game.node.item.Item
import core.plugin.Initializable
import core.plugin.Plugin
private const val GIANNE_DOUGH = 2171
private const val CRUNCHY_TRAY = 2165
private const val RAW_CRUNCHIES = 2202
/**
* Handles adding GIANNE_DOUGH to CRUNCHY_TRAY to produce RAW_CRUNCHIES
* @author Ceikry
*/
@Initializable
class GnomeCrunchyTrayFiller : UseWithHandler(GIANNE_DOUGH) {
override fun newInstance(arg: Any?): Plugin<Any> {
addHandler(CRUNCHY_TRAY, ITEM_TYPE,this)
return this
}
override fun handle(event: NodeUsageEvent?): Boolean {
event ?: return false
event.player.inventory.remove(event.used.asItem())
event.player.inventory.remove(event.usedWith.asItem())
event.player.inventory.add(Item(RAW_CRUNCHIES))
return true
}
}
@@ -1,233 +0,0 @@
package core.game.content.activity.mta
import core.tools.Items
import core.game.node.Node
import core.game.node.entity.Entity
import core.game.node.entity.combat.equipment.SpellType
import core.game.node.entity.player.Player
import core.game.node.entity.player.link.SpellBookManager.SpellBook
import core.game.node.entity.player.link.audio.Audio
import core.game.node.item.Item
import core.game.world.update.flag.context.Animation
import core.game.world.update.flag.context.Graphics
import core.plugin.Plugin
import core.game.content.activity.mta.impl.EnchantingZone
import core.game.content.activity.mta.impl.EnchantingZone.Shapes
import core.game.node.entity.skill.magic.MagicSpell
import core.game.node.entity.skill.magic.Runes
/**
* Represents the enchant spells.
* @author Ceikry
*/
class EnchantSpell : MagicSpell {
/**
* The enchantable jewellery array.
*/
private val jewellery: HashMap<Int,Item>?
/**
* Constructs a new `EnchantSpell` `Object`.
*/
constructor() {
jewellery = null
}
/**
* Constructs a new `EnchantSpell` `Object`.
* @param level The level required.
* @param jewellery The jewellery this spell is able to echant.
* @param runes The runes required.
*/
constructor(level: Int, experience: Double, jewellery: HashMap<Int,Item>, runes: Array<Item>?) : super(SpellBook.MODERN, level, experience, ANIMATION, GRAPHIC, Audio(115, 1, 0), runes) {
this.jewellery = jewellery
}
override fun cast(entity: Entity, target: Node): Boolean {
if (target !is Item || entity !is Player) {
return false
}
entity.interfaceManager.setViewedTab(6)
val enchanted = jewellery?.getOrDefault(target.id,null)
if (enchanted == null) {
entity.packetDispatch.sendMessage("You can't use this spell on this item.")
return false
}
if (!meetsRequirements(entity, true, true)) {
return false
}
if (entity.inventory.remove(target)) {
visualize(entity, target)
entity.inventory.add(enchanted)
}
//MTA-Specific Code
if (entity.zoneMonitor.isInZone("Enchantment Chamber")) {
entity.graphics(Graphics.create(237, 110))
var pizazz = 0
if (target.id == 6903) {
pizazz = (if (getSpellId() == 5) 1 else if (getSpellId() == 16) 2 else if (getSpellId() == 28) 3 else if (getSpellId() == 36) 4 else if (getSpellId() == 51) 5 else 6) * 2
} else {
val shape = Shapes.forItem(target)
if (shape != null) {
var convert = entity.getAttribute("mta-convert", 0)
convert += 1
if (convert >= 10) {
pizazz = if (getSpellId() == 5) 1 else if (getSpellId() == 16) 2 else if (getSpellId() == 28) 3 else if (getSpellId() == 36) 4 else if (getSpellId() == 51) 5 else 6
convert = 0
}
entity.setAttribute("mta-convert", convert)
if (shape == EnchantingZone.BONUS_SHAPE) {
pizazz += 1
entity.sendMessage("You get " + pizazz + " bonus point" + (if (pizazz != 1) "s" else "") + "!")
}
}
}
if (pizazz != 0) {
EnchantingZone.ZONE.incrementPoints(entity, MTAType.ENCHANTERS.ordinal, pizazz)
}
}
return true
}
override fun getDelay(): Int {
return 1
}
override fun getExperience(player: Player): Double {
return if (player.zoneMonitor.isInZone("Enchantment Chamber")) {
experience - experience * 0.75
} else experience
}
override fun newInstance(arg: SpellType?): Plugin<SpellType>? {
/**
* Enchant Sapphire Jewelry (Lvl-1 Enchant)
*/
SpellBook.MODERN.register(5, EnchantSpell(7, 17.5,
hashMapOf(
//Begin Jewelry Enchantments
Items.SAPPHIRE_RING_1637 to Item(Items.RING_OF_RECOIL_2550),
Items.SAPPHIRE_NECKLACE_1656 to Item(Items.GAMES_NECKLACE8_3853),
Items.SAPPHIRE_AMULET_1694 to Item(Items.AMULET_OF_MAGIC_1727),
Items.SAPPHIRE_BRACELET_11072 to Item(Items.BRACELET_OF_CLAY_11074),
//Begin MTA-specific enchantments
Items.CUBE_6899 to Item(Items.ORB_6902),
Items.CYLINDER_6898 to Item(Items.ORB_6902),
Items.ICOSAHEDRON_6900 to Item(Items.ORB_6902),
Items.PENTAMID_6901 to Item(Items.ORB_6902),
Items.DRAGONSTONE_6903 to Item(Items.ORB_6902)
),
arrayOf(Item(Items.COSMIC_RUNE_564,1), Item(Items.WATER_RUNE_555,1))))
/**
* Enchant Emerald Jewelry (Lvl-2 Enchant)
*/
SpellBook.MODERN.register(16, EnchantSpell(27, 37.0,
hashMapOf(
//Begin Jewelry Enchantments
Items.EMERALD_RING_1639 to Item(Items.RING_OF_DUELLING8_2552),
Items.EMERALD_NECKLACE_1658 to Item(Items.BINDING_NECKLACE_5521),
Items.EMERALD_AMULET_1696 to Item(Items.AMULET_OF_DEFENCE_1729),
Items.EMERALD_BRACELET_11076 to Item(Items.CASTLEWAR_BRACE3_11080),
//Begin MTA-Specific Enchantments
Items.CUBE_6899 to Item(Items.ORB_6902),
Items.CYLINDER_6898 to Item(Items.ORB_6902),
Items.ICOSAHEDRON_6900 to Item(Items.ORB_6902),
Items.PENTAMID_6901 to Item(Items.ORB_6902),
Items.DRAGONSTONE_6903 to Item(Items.ORB_6902)
),
arrayOf(Item(Runes.COSMIC_RUNE.id, 1), Item(Runes.AIR_RUNE.id, 3))))
/**
* Enchant Ruby Jewelry (Lvl-3 Enchant)
*/
SpellBook.MODERN.register(28, EnchantSpell(49, 59.0,
hashMapOf(
//Begin Jewelry Enchantments
Items.RUBY_RING_1641 to Item(Items.RING_OF_FORGING_2568),
Items.RUBY_NECKLACE_1660 to Item(Items.DIGSITE_PENDANT_5_11194),
Items.RUBY_AMULET_1698 to Item(Items.AMULET_OF_STRENGTH_1725),
Items.RUBY_BRACELET_11085 to Item(Items.INOCULATION_BRACE_11088),
//Begin MTA-Specific Enchantments
Items.CUBE_6899 to Item(Items.ORB_6902),
Items.CYLINDER_6898 to Item(Items.ORB_6902),
Items.ICOSAHEDRON_6900 to Item(Items.ORB_6902),
Items.PENTAMID_6901 to Item(Items.ORB_6902),
Items.DRAGONSTONE_6903 to Item(Items.ORB_6902)
),
arrayOf(Item(Runes.COSMIC_RUNE.id, 1), Item(Runes.FIRE_RUNE.id, 5))))
/**
* Enchant Diamond Jewelry (Lvl-4 Enchant)
*/
SpellBook.MODERN.register(36, EnchantSpell(57, 67.0,
hashMapOf(
Items.DIAMOND_RING_1643 to Item(Items.RING_OF_LIFE_2570),
Items.DIAMOND_NECKLACE_1662 to Item(Items.PHOENIX_NECKLACE_11090),
Items.DIAMOND_AMULET_1700 to Item(Items.AMULET_OF_POWER_1731),
Items.DIAMOND_BRACELET_11092 to Item(Items.FORINTHRY_BRACE5_11096),
//Begin MTA-Specific Enchantments
Items.CUBE_6899 to Item(Items.ORB_6902),
Items.CYLINDER_6898 to Item(Items.ORB_6902),
Items.ICOSAHEDRON_6900 to Item(Items.ORB_6902),
Items.PENTAMID_6901 to Item(Items.ORB_6902),
Items.DRAGONSTONE_6903 to Item(Items.ORB_6902)
),
arrayOf(Item(Runes.COSMIC_RUNE.id, 1), Item(Runes.EARTH_RUNE.id, 10))))
/**
* Enchant Dragonstone Jewelry (Lvl-5 Enchant)
*/
SpellBook.MODERN.register(51, EnchantSpell(68, 78.0,
hashMapOf(
//Begin Jewelry Enchantment
Items.DRAGONSTONE_RING_1645 to Item(14646),
Items.DRAGON_NECKLACE_1664 to Item(Items.SKILLS_NECKLACE4_11105),
Items.DRAGONSTONE_AMMY_1702 to Item(Items.AMULET_OF_GLORY4_1712),
Items.DRAGON_BRACELET_11115 to Item(Items.COMBAT_BRACELET4_11118),
//Begin MTA-Specific Enchantments
Items.CUBE_6899 to Item(Items.ORB_6902),
Items.CYLINDER_6898 to Item(Items.ORB_6902),
Items.ICOSAHEDRON_6900 to Item(Items.ORB_6902),
Items.PENTAMID_6901 to Item(Items.ORB_6902),
Items.DRAGONSTONE_6903 to Item(Items.ORB_6902)
),
arrayOf(Item(Runes.COSMIC_RUNE.id, 1), Item(Runes.WATER_RUNE.id, 15), Item(Runes.EARTH_RUNE.id, 15))))
/**
* Enchant Onyx Jewelry (Lvl-6 Enchant)
*/
SpellBook.MODERN.register(61, EnchantSpell(87, 97.0,
hashMapOf(
//Begin Jewelry Enchantments
Items.ONYX_RING_6575 to Item(Items.RING_OF_STONE_6583),
Items.ONYX_NECKLACE_6577 to Item(Items.BERSERKER_NECKLACE_11128),
Items.ONYX_AMULET_6581 to Item(Items.AMULET_OF_FURY_6585),
Items.ONYX_BRACELET_11130 to Item(Items.REGEN_BRACELET_11133),
//Begin MTA-Specific Enchantments
Items.CUBE_6899 to Item(Items.ORB_6902),
Items.CYLINDER_6898 to Item(Items.ORB_6902),
Items.ICOSAHEDRON_6900 to Item(Items.ORB_6902),
Items.PENTAMID_6901 to Item(Items.ORB_6902),
Items.DRAGONSTONE_6903 to Item(Items.ORB_6902)
),
arrayOf(Item(Runes.COSMIC_RUNE.id, 1), Item(Runes.FIRE_RUNE.id, 20), Item(Runes.EARTH_RUNE.id, 20))))
return this
}
companion object {
/**
* The animation.
*/
private val ANIMATION = Animation.create(712)
/**
* The graphic.
*/
private val GRAPHIC = Graphics(114, 96)
}
}
@@ -1,72 +0,0 @@
package core.game.content.activity.pestcontrol
import core.game.node.entity.player.Player
import core.game.world.map.Location
import core.game.world.map.zone.ZoneBorders
import plugin.ai.minigamebots.pestcontrol.PestControlTestBot
import plugin.ai.minigamebots.pestcontrol.PestControlTestBot2
import kotlin.random.Random
object PestControlHelper {
var GATE_ENTRIES = listOf(14233, 14235)
var Portals_AttackableN = listOf(6142, 6143, 6144, 6145).toMutableList()
var Portals_AttackableI = listOf(6150, 6151, 6152, 6153).toMutableList()
var Portals_AttackableV = listOf(7551, 7552, 7553, 7554).toMutableList()
val portalIds = arrayOf(
6142, 6143, 6144, 6145, 6146, 6147, 6148, 6149,
6150, 6151, 6152, 6153, 6154, 6155, 6156, 6157,
7551, 7552, 7553, 7554, 7555, 7556, 7557, 7558)
var PORTAL_ENTRIES = listOf(*portalIds)
val PestControlLanderIntermediate = Location.create(2644, 2646, 0)
val PestControlLanderNovice = Location.create(2657, 2642, 0)
val PestControlIslandLocation = Location.create(2659, 2676, 0)
val PestControlIslandLocation2 = Location.create(2659, 2676, 0)
var pclocations =
if (Random.nextBoolean()){ Location.create(2667, 2653,0)
}else if (Random.nextBoolean()){ Location.create(2658, 2654, 0)
}else if (Random.nextBoolean()){ Location.create(2651, 2659, 0)
}else if(Random.nextBoolean()){ Location.create(2650, 2664,0)
}else{ Location.create(2665, 2660, 0) }
////////////Begin functions///////////////
fun isInPestControlInstance(p: Player): Boolean {
return p.getAttribute<Any?>("pc_zeal") != null
}
enum class BoatInfo(var boatBorder: ZoneBorders, var outsideBoatBorder: ZoneBorders, var ladderId: Int) {
NOVICE(ZoneBorders(2660, 2638, 2663, 2643), ZoneBorders(2658, 2635, 2656, 2646), 14315),
INTERMEDIATE(ZoneBorders(2638, 2642, 2641, 2647), ZoneBorders(2645, 2639, 2643, 2652), 25631),
VETERAN(ZoneBorders(2632, 2649, 2635, 2654), ZoneBorders(2638, 2652, 2638, 2655), 25632);
}
fun landerContainsLoc(l: Location?): Boolean {
for (i in BoatInfo.values()) if (i.boatBorder.insideBorder(l)) return true
return false
}
fun outsideGangplankContainsLoc(l: Location?): Boolean {
for (i in BoatInfo.values()) if (i.outsideBoatBorder.insideBorder(l)) return true
return false
}
fun landerContainsLoc2(l: Location?): Boolean {
for (n in BoatInfo.values()) if (n.boatBorder.insideBorder(l)) return true
return false
}
fun outsideGangplankContainsLoc2(l: Location?): Boolean {
for (n in BoatInfo.values()) if (n.outsideBoatBorder.insideBorder(l)) return true
return false
}
fun getMyPestControlSession1(p: PestControlTestBot): PestControlSession? {
return p.getExtension(PestControlSession::class.java)
}
fun getMyPestControlSession2(p: PestControlTestBot2): PestControlSession? {
return p.getExtension(PestControlSession::class.java)
}
}
@@ -1,89 +0,0 @@
package core.game.content.activity.pyramidplunder
import core.game.component.Component
import core.game.node.entity.player.Player
import core.game.system.task.Pulse
import core.game.world.GameWorld
import core.game.world.map.Location
import core.tools.Components
import core.tools.RandomFunction
class PlunderSession(val player: Player) {
var door1Open: Boolean = false
var door2Open: Boolean = false
var door3Open: Boolean = false
var door4Open: Boolean = false
var chestHidden: Boolean = false
var chestOpen: Boolean = false
var coffinHidden: Boolean = false
var coffinOpen: Boolean = false
var timeCounter: Int = 1
var correctDoorIndex: Int = RandomFunction.random(1000) % 4
var isActive = false
fun init(){
player.setAttribute("plunder-session",this)
GameWorld.Pulser.submit(PlunderPulse(player))
player.interfaceManager.openOverlay(Component(Components.ntk_overlay_428))
isActive = true
}
fun updateOverlay(){
player.configManager.set(821,getConfig())
}
fun resetVars(){
chestOpen = false
chestHidden = false
coffinHidden = false
coffinOpen = false
door1Open = false
door2Open = false
door3Open = false
door4Open = false
correctDoorIndex = RandomFunction.random(1000) % 4
}
fun getConfig(): Int{
var config = 0
if(coffinOpen) config = 1
if(coffinHidden) config = (config or (1 shl 1))
if(chestOpen) config = (config or (1 shl 2))
if(chestHidden) config = (config or (1 shl 3))
if(door1Open) config = (config or (1 shl 9))
if(door2Open) config = (config or (1 shl 10))
if(door3Open) config = (config or (1 shl 11))
if(door4Open) config = (config or (1 shl 12))
return (config or (timeCounter shl 25))
}
fun setDoorOpen(index: Int){
when(index){
0 -> door1Open = true
1 -> door2Open = true
2 -> door3Open = true
3 -> door4Open = true
}
}
class PlunderPulse(val player: Player) : Pulse(){
var ticks = 0
var overlayConfig = 0
val session: PlunderSession? = player.getAttribute("plunder-session",null)
override fun pulse(): Boolean {
session ?: return false
if(ticks++ % 8 == 0){
session.timeCounter++
session.updateOverlay()
}
if(session.timeCounter > 63){
player.properties.teleportLocation = Location.create(3286, 2803, 0)
player.dialogueInterpreter.sendDialogue("You ran out of time and the mummy kicked you","out.")
player.configManager.set(822,0)
player.configManager.set(821,0)
}
return session.timeCounter > 63 || !session.isActive
}
}
}
@@ -1,46 +0,0 @@
package core.game.content.ame.events
import core.game.component.Component
import core.game.interaction.DestinationFlag
import core.game.interaction.MovementPulse
import core.game.interaction.Option
import core.game.node.entity.npc.NPC
import core.game.node.entity.player.Player
import core.game.world.GameWorld
import core.plugin.Initializable
import core.plugin.Plugin
import core.game.content.quest.PluginInteraction
import core.game.content.quest.PluginInteractionManager
@Initializable
class SandwichLadyHandler : PluginInteraction(3117){
override fun handle(player: Player?, npc: NPC?, option: Option?): Boolean {
class MoveTo : MovementPulse(player,DestinationFlag.ENTITY.getDestination(player,npc)){
override fun pulse(): Boolean {
if(player?.antiMacroHandler?.hasEvent()!! && player.antiMacroHandler.event.name == "Sandwich Lady") {
player.interfaceManager?.open(Component(297))
npc?.clear()
} else {
player.sendMessage("She isn't interested in you.")
}
return true
}
}
if(option?.name?.toLowerCase() == "talk-to"){
GameWorld.submit(MoveTo())
return true
}
return false
}
override fun fireEvent(identifier: String?, vararg args: Any?): Any {
return Unit
}
override fun newInstance(arg: Any?): Plugin<Any> {
PluginInteractionManager.register(this,PluginInteractionManager.InteractionType.NPC)
return this
}
}
@@ -1,48 +0,0 @@
package core.game.content.ame.events
import core.game.component.Component
import core.game.component.ComponentDefinition
import core.game.component.ComponentPlugin
import core.game.node.entity.player.Player
import core.game.node.item.GroundItemManager
import core.game.node.item.Item
import core.plugin.Initializable
import core.plugin.Plugin
import core.tools.Items
@Initializable
class SandwichLadyInterface : ComponentPlugin(){
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 handle(player: Player?, component: Component?, opcode: Int, button: Int, slot: Int, itemId: Int): Boolean {
var item = Item(0)
when(button) {
7 -> {item = Item(baguette)}
8 -> {item = Item(triangle_sandwich)}
9 -> {item = Item(sandwich)}
10 -> {item = Item(roll)}
11 -> {item = Item(pie)}
12 -> {item = Item(kebab)}
13 -> {item = Item(chocobar)}
}
if(item.id != 0){
player?.let { if(it.inventory.add(item)) else GroundItemManager.create(item,it) }
player?.interfaceManager?.close()
player?.antiMacroHandler?.event?.terminate()
return true
}
return false
}
override fun newInstance(arg: Any?): Plugin<Any> {
ComponentDefinition.put(297,this)
return this
}
}
@@ -1,84 +0,0 @@
package core.game.content.ame.events
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
import core.game.content.ame.AntiMacroEvent
import core.game.content.ame.AntiMacroHandler
import java.nio.ByteBuffer
@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)
}
}
}
@@ -1,13 +0,0 @@
package core.game.content.consumable.effects
import core.game.node.entity.player.Player
import core.game.content.consumable.ConsumableEffect
import core.game.node.entity.skill.Skills
class RestoreSummoning(val percent: Double) : ConsumableEffect(){
override fun activate(p: Player?) {
var amt = (p!!.skills!!.getStaticLevel(Skills.SUMMONING) * percent).toInt()
if(amt + p.skills.getLevel(Skills.SUMMONING) > p.skills.getStaticLevel(Skills.SUMMONING)) amt = p.skills.getStaticLevel(Skills.SUMMONING) - p.skills.getLevel(Skills.SUMMONING)
p.skills.setLevel(Skills.SUMMONING, p.skills.getLevel(Skills.SUMMONING) + amt)
}
}
@@ -1,36 +0,0 @@
package core.game.content.dialogue
import core.game.node.entity.npc.NPC
import core.game.node.entity.player.Player
import core.plugin.Initializable
/**
* Dialogue for Aberab
* @author qmqz
*/
@Initializable
class AberabDialogue(player: Player? = null) : DialoguePlugin(player){
override fun open(vararg args: Any?): Boolean {
npc = args[0] as NPC
npc(FacialExpression.CHILD_SUSPICIOUS,"Grr ... Get out of my way...")
stage = 99
return true
}
override fun handle(interfaceId: Int, buttonId: Int): Boolean {
when(stage){
99 -> end()
}
return true
}
override fun newInstance(player: Player?): DialoguePlugin {
return AberabDialogue(player)
}
override fun getIds(): IntArray {
return intArrayOf(1432)
}
}
@@ -1,35 +0,0 @@
package core.game.content.dialogue
import core.game.node.entity.npc.NPC
import core.game.node.entity.player.Player
import core.plugin.Initializable
/**
* @author qmqz
*/
@Initializable
class AchiettiesDialogue(player: Player? = null) : DialoguePlugin(player){
override fun open(vararg args: Any?): Boolean {
npc = args[0] as NPC
npc(FacialExpression.FRIENDLY,"Greetings. Welcome to the Heroes' Guild.")
stage = 99
return true
}
override fun handle(interfaceId: Int, buttonId: Int): Boolean {
when(stage){
99 -> end()
}
return true
}
override fun newInstance(player: Player?): DialoguePlugin {
return AchiettiesDialogue(player)
}
override fun getIds(): IntArray {
return intArrayOf(796)
}
}
@@ -1,42 +0,0 @@
package core.game.content.dialogue
import core.game.node.entity.npc.NPC
import core.game.node.entity.player.Player
import core.plugin.Initializable
import core.tools.RandomFunction
import java.util.*
import java.util.Arrays
/**
* @author qmqz
*/
@Initializable
class AfflictedDialogue : DialoguePlugin {
private val chats = arrayOf("ughugh", "knows'is", "knows'is", "nots", "pirsl", "wot's", "zurgle", "gurghl", "mee's", "seysyi", "sfriess", "says")
override fun open(vararg args: Any): Boolean {
npc = args[0] as NPC
chats.shuffle()
interpreter.sendDialogues( npc, FacialExpression.ASKING, chats.copyOfRange(0, RandomFunction.random(1, 6)).contentToString()
.replace("[", "").replace("]", "").replace(",", ""))
return true
}
constructor()
constructor(player: Player?) : super(player)
override fun getIds(): IntArray {
return intArrayOf(1257, 1258, 1261, 1262)
}
override fun handle(interfaceId: Int, buttonId: Int): Boolean {
end()
return true
}
override fun newInstance(player: Player): DialoguePlugin {
return AfflictedDialogue(player)
}
}
@@ -1,172 +0,0 @@
package core.game.content.dialogue
import core.game.node.entity.npc.NPC
import core.game.node.entity.player.Player
import core.plugin.Initializable
/**
* @author qmqz
*/
@Initializable
class AfrahDialogue : DialoguePlugin {
private val conversations = arrayOf (0, 4, 10, 11, 15, 17, 20, 22, 23, 24, 29, 32)
override fun open(vararg args: Any): Boolean {
player(FacialExpression.ASKING, "Hi!")
stage = conversations.random()
npc = args[0] as NPC
return true
}
constructor() {}
constructor(player: Player?) : super(player) {}
override fun getIds(): IntArray {
return intArrayOf(968)
}
override fun handle(interfaceId: Int, buttonId: Int): Boolean {
when (stage) {
0 -> {
npc(FacialExpression.ASKING, "Ooh. This is exciting!")
stage++
}
1 -> {
player(FacialExpression.ASKING, "Yup!")
stage = 99
}
2 -> {
npc(FacialExpression.ASKING, "I wouldn't want to be the poor guy that has to", "clean up after the duels.")
stage++
}
3 -> {
player(FacialExpression.ASKING, "Me neither.")
stage = 99
}
4 -> {
npc(FacialExpression.ASKING, "My son just won his first duel!")
stage++
}
5 -> {
player(FacialExpression.ASKING, "Congratulations!")
stage++
}
6 -> {
npc(FacialExpression.ASKING, "He ripped his opponent in half!")
stage++
}
7 -> {
player(FacialExpression.ASKING, "That's gotta hurt!")
stage++
}
8 -> {
npc(FacialExpression.ASKING, "He's only 10 as well!")
stage++
}
9 -> {
player(FacialExpression.ASKING, "You gotta start 'em young!")
stage = 99
}
10 -> {
npc(FacialExpression.ASKING, "Hmph.")
stage = 99
}
11 -> {
npc(FacialExpression.ASKING, "My favourite fighter is Mubariz!")
stage++
}
12 -> {
player(FacialExpression.ASKING, "The guy at the information kiosk?")
stage++
}
13 -> {
npc(FacialExpression.ASKING, "Yeah! He rocks!")
stage++
}
14 -> {
player(FacialExpression.ASKING, "Takes all sorts, I guess.")
stage = 99
}
15 -> {
npc(FacialExpression.ASKING, "Hi! I'm here to watch the duels!")
stage++
}
16 -> {
player(FacialExpression.ASKING, "Me too!")
stage = 99
}
17 -> {
npc(FacialExpression.ASKING, "Did you know they think this place dates","back to the second age?!")
stage++
}
18 -> {
player(FacialExpression.ASKING, "Really?")
stage++
}
19 -> {
npc(FacialExpression.ASKING, "Yeah. The guy at the information kiosk was telling me.")
stage = 99
}
20 -> {
npc(FacialExpression.ANGRY, "Can't you see I'm watching the duels?")
stage++
}
21 -> {
player(FacialExpression.SAD, "I'm sorry!")
stage = 99
}
22 -> {
npc(FacialExpression.ASKING, "Well. This beats doing the shopping!")
stage = 99
}
23 -> {
npc(FacialExpression.ASKING, "Hi!")
stage = 99
}
24 -> {
npc(FacialExpression.ASKING, "Knock knock!")
stage++
}
25 -> {
player(FacialExpression.ASKING, "Who's there?")
stage++
}
26 -> {
npc(FacialExpression.ASKING, "Boo!")
stage++
}
27 -> {
player(FacialExpression.ASKING, "Boo who?")
stage++
}
28 -> {
npc(FacialExpression.LAUGH, "Don't cry, it's just me!")
stage = 99
}
29 -> {
npc(FacialExpression.ASKING, "Why did the skeleton burp?")
stage++
}
30 -> {
player(FacialExpression.ASKING, "I don't know?")
stage++
}
31 -> {
npc(FacialExpression.ASKING, "'Cause it didn't have the guts to fart!")
stage = 99
}
32 -> {
npc(FacialExpression.ASKING, "Waaaaassssssuuuuupp?!.")
stage = 99
}
99 -> end()
}
return true
}
override fun newInstance(player: Player): DialoguePlugin {
return AfrahDialogue(player)
}
}
@@ -1,54 +0,0 @@
package core.game.content.dialogue
import core.game.node.entity.npc.NPC
import core.game.node.entity.player.Player
import core.plugin.Initializable
/**
* @author qmqz
*/
@Initializable
class AgilityBossDialogue(player: Player? = null) : DialoguePlugin(player){
override fun open(vararg args: Any?): Boolean {
npc = args[0] as NPC
if(player.equipment.contains(4202,1)) {
player(FacialExpression.ASKING,"How do I use the agility course?").also { stage = 0 }
} else {
npc(FacialExpression.CHILD_SUSPICIOUS,"Grrr - you don't belong in here, human!").also { stage = 99 }
}
return true
}
override fun handle(interfaceId: Int, buttonId: Int): Boolean {
when(stage){
0 -> npc(FacialExpression.CHILD_NORMAL,"I'll throw you a stick, which you need to",
"fetch as quickly as possible, ",
"from the area beyond the pipes.").also { stage++ }
1 -> npc(FacialExpression.CHILD_NORMAL,"Be wary of the deathslide - you must hang by your teeth,",
"and if your strength is not up to the job you will",
"fall into a pit of spikes. Also, I would advise not",
"carrying too much extra weight.").also { stage++ }
2 -> npc(FacialExpression.CHILD_NORMAL,"Bring the stick back to the werewolf waiting at",
"the end of the death slide to get your agility bonus.").also { stage++ }
3 ->npc(FacialExpression.CHILD_NORMAL,"I will throw your stick as soon as you jump onto the",
"first stone.").also { stage = 99 }
99 -> end()
}
return true
}
override fun newInstance(player: Player?): DialoguePlugin {
return AgilityBossDialogue(player)
}
override fun getIds(): IntArray {
return intArrayOf(1661)
}
}
@@ -1,65 +0,0 @@
package core.game.content.dialogue
import core.game.node.entity.npc.NPC
import core.game.node.entity.player.Player
import core.plugin.Initializable
/**
* @author qmqz
*/
@Initializable
class AgmundiDialogue(player: Player? = null) : DialoguePlugin(player){
override fun open(vararg args: Any?): Boolean {
npc = args[0] as NPC
npc(FacialExpression.CHILD_NORMAL,"Oh no, not another human... what do you want then?")
stage = 0
return true
}
override fun handle(interfaceId: Int, buttonId: Int): Boolean {
when(stage){
0 -> player(FacialExpression.ASKING, "Oh, do you get humans here often?").also { stage++ }
1 -> npc(FacialExpression.CHILD_SUSPICIOUS, "Not that often, no, but sometimes.").also { stage++ }
2 -> npc(FacialExpression.CHILD_THINKING, "Of course, since you people are too big for dwarven",
"clothes, they typically don't stay very long.").also { stage++ }
3 -> player(FacialExpression.SUSPICIOUS, "Why don't you make bigger clothes then?").also { stage++ }
4 -> npc(FacialExpression.CHILD_GUILTY, "What'd be the point? Besides, I don't make", "these clothes myself.").also { stage++ }
5 -> options ("Who makes these clothes then?", "I still want to buy your clothes.", "So do you have any quests for me?").also { stage++ }
6 -> when(buttonId){
1 -> player(FacialExpression.GUILTY, "Who makes the clothes then?").also { stage = 10 }
2 -> npc.openShop(player)
3 -> npc(FacialExpression.CHILD_SUSPICIOUS,"Quests? Why would I have any quests?").also { stage = 20 }
}
10 -> npc(FacialExpression.CHILD_NORMAL,"Oh, my sister, she lives in Keldagrim-East.",
"Has a little stall on the other side of",
"the Kelda.").also { stage++ }
11 -> npc(FacialExpression.CHILD_NORMAL,"If she only worked a little harder, like me,",
"she wouldn't have to live in the sewers of the city.",
"Shame really.").also { stage++ }
12 -> player("The sewers? Your sister lives in the sewers?").also { stage++ }
13 -> npc(FacialExpression.CHILD_SAD,"Keldagrim-East, such a ghastly place.",
"Not civil, polite and clean like we are in the West.").also { stage++ }
14 -> player(FacialExpression.SUSPICIOUS, "Uh-huh.").also { stage=99 }
20 -> player("Oh, just anything to do would be fine.").also { stage++ }
21 -> npc(FacialExpression.CHILD_NORMAL,"No, not right now... maybe I'll have something",
"for you to do later, but nothing at the moment.").also { stage = 99 }
99 -> end()
}
return true
}
override fun newInstance(player: Player?): DialoguePlugin {
return AgmundiDialogue(player)
}
override fun getIds(): IntArray {
return intArrayOf(2161)
}
}
@@ -1,49 +0,0 @@
package core.game.content.dialogue
import core.game.component.Component
import core.game.node.entity.player.Player
import core.plugin.Initializable
import core.game.content.activity.gnomecooking.GC_BASE_ATTRIBUTE
import core.game.content.activity.gnomecooking.GC_TUT_PROG
@Initializable
class AluftGianneJrDialogue(player: Player? = null) : DialoguePlugin(player) {
var tutorialStage = -1
override fun newInstance(player: Player?): DialoguePlugin {
return AluftGianneJrDialogue(player)
}
override fun npc(vararg messages: String?): Component {
return super.npc(FacialExpression.OLD_NORMAL,*messages)
}
override fun open(vararg args: Any?): Boolean {
tutorialStage = player.getAttribute("$GC_BASE_ATTRIBUTE:$GC_TUT_PROG",-1)
if(tutorialStage == -1){
player("Hey can I get a job here?").also { stage = 0 }
} else {
npc("Having fun?").also { stage = 1000 }
}
return true
}
override fun handle(interfaceId: Int, buttonId: Int): Boolean {
when(stage){
0 -> npc("Sure, go talk to my dad. I'll put","a good word in!").also { stage++ }
1 -> player(FacialExpression.THINKING,"Th-thanks...?").also { stage++ }
2 -> {
end()
player.setAttribute("/save:$GC_BASE_ATTRIBUTE:$GC_TUT_PROG",0)
}
1000 -> end()
}
return true
}
override fun getIds(): IntArray {
return intArrayOf(4572)
}
}
@@ -1,197 +0,0 @@
package core.game.content.dialogue
import core.game.component.Component
import core.tools.Items
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.GameWorld
import core.plugin.Initializable
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
import core.game.content.activity.gnomecooking.*
import core.tools.stringtools.colorize
import java.util.concurrent.TimeUnit
val gnomeItems = arrayOf(Items.FRUIT_BATTA_2277,Items.TOAD_BATTA_2255,Items.CHEESE_PLUSTOM_BATTA_2259,Items.WORM_BATTA_2253,Items.VEGETABLE_BATTA_2281,
Items.CHOCOLATE_BOMB_2185,Items.VEG_BALL_2195,Items.TANGLED_TOADS_LEGS_2187,Items.WORM_HOLE_2191,Items.TOAD_CRUNCHIES_2217,Items.WORM_CRUNCHIES_2205,Items.CHOCCHIP_CRUNCHIES_2209,Items.SPICY_CRUNCHIES_2213,Items.FRUIT_BLAST_9514,Items.DRUNK_DRAGON_2092,Items.CHOC_SATURDAY_2074,
Items.SHORT_GREEN_GUY_9510,Items.BLURBERRY_SPECIAL_9520,Items.PINEAPPLE_PUNCH_9512,Items.WIZARD_BLIZZARD_9508)
val ALUFT_ALOFT_BOX = Item(Items.ALUFT_ALOFT_BOX_9477)
@Initializable
class AluftGianneSnrDialogue(player: Player? = null) : DialoguePlugin(player) {
var tutorialProgress = -1
var tutorialComplete = false
override fun newInstance(player: Player?): DialoguePlugin {
return AluftGianneSnrDialogue(player)
}
override fun npc(vararg messages: String?): Component {
return super.npc(FacialExpression.OLD_NORMAL,*messages)
}
override fun open(vararg args: Any?): Boolean {
tutorialComplete = player.getAttribute("$GC_BASE_ATTRIBUTE:$GC_TUT_FIN",false)
tutorialProgress = player.getAttribute("$GC_BASE_ATTRIBUTE:$GC_TUT_PROG",-1)
if(tutorialComplete){
npc("Hello, adventurer. How can I help you?")
stage = 300
return true
}
if(tutorialProgress == -1){
npc("Who are you and what do you want?")
stage = 1000
return true
}
if(tutorialProgress == 0){
npc("Hello, adventurer. I heard from my son","that you'd like to do some work.")
stage = 0
return true
}
npc("Hello, adventurer. How goes the training?")
stage = tutorialProgress
return true
}
override fun handle(interfaceId: Int, buttonId: Int): Boolean {
when(stage){
0 -> player(FacialExpression.HAPPY,"Yes, how do I get started?").also { stage++ }
1 -> npc("Well first thing's first I need to teach","you how to cook!").also { stage++ }
2 -> player(FacialExpression.THINKING,"But I already-").also { stage++ }
3 -> npc("Stop whatever it is you're saying, no one knows","how to cook gnome food except gnomes!").also { stage++ }
4 -> player("Alright, go on...").also{stage++}
5 -> npc("Alright, first thing I want you to do is","make me a toad batta. Here's all the","ingredients, now get to work!").also { stage++ }
6 -> {
end()
val items = arrayOf(Item(Items.BATTA_TIN_2164),Item(Items.GIANNE_DOUGH_2171),Item(Items.EQUA_LEAVES_2128),Item(Items.GNOME_SPICE_2169),Item(Items.CHEESE_1985), Item(Items.TOADS_LEGS_2152))
if(!player.inventory.hasSpaceFor(*items)){
player.dialogueInterpreter.sendDialogue("You don't have space for the items.")
} else {
player.inventory.add(*items)
player.setAttribute("/save:$GC_BASE_ATTRIBUTE:$GC_TUT_PROG",10)
}
}
//Toad Batta completion check
10 -> {
if(player.inventory.containsItem(Item(Items.TOAD_BATTA_2255))){
player("Very well! I have the batta right here!").also { stage = 11 }
} else {
player("Not well, I haven't got the batta yet.").also { stage = 1000 }
}
}
11 -> npc("Very well, hand it over then!").also { stage++ }
12 -> {
player.inventory.remove(Item(Items.TOAD_BATTA_2255))
player.setAttribute("/save:$GC_BASE_ATTRIBUTE:$GC_TUT_PROG",13)
player.dialogueInterpreter.sendDialogue("You hand over the toad batta.").also { stage++ }
}
13 -> npc("Very nicely done. Now I would like you to make me","toad crunchies. Here's everything you need.").also { stage++ }
14 -> {
end()
val items = arrayOf(Item(Items.CRUNCHY_TRAY_2165),Item(Items.EQUA_LEAVES_2128),Item(Items.GIANNE_DOUGH_2171),Item(Items.TOADS_LEGS_2152,2))
if(!player.inventory.hasSpaceFor(*items)){
player.dialogueInterpreter.sendDialogue("You don't have enough space for the items.")
} else {
player.inventory.add(*items)
player.setAttribute("/save:$GC_BASE_ATTRIBUTE:$GC_TUT_PROG",15)
}
}
//Toad Crunchies completion check
15 -> {
if(player.inventory.containsItem(Item(Items.TOAD_CRUNCHIES_2217))){
player("Very well! I have the crunchies right here!").also { stage = 16 }
} else {
player("Not well, I haven't got the crunchies yet.").also { stage = 1000 }
}
}
16 -> npc("Very well, hand it over then!").also { stage++ }
17 -> {
player.inventory.remove(Item(Items.TOAD_CRUNCHIES_2217))
player.setAttribute("/save:$GC_BASE_ATTRIBUTE:$GC_TUT_PROG",18)
player.dialogueInterpreter.sendDialogue("You hand over the toad crunchies.").also { stage++ }
}
18 -> npc("Very nice indeed. Now I'd like you to go see my friend","Blurberry at the bar.").also { stage = 1000 }
//Dialogue for getting jobs
300 -> options("I'd like to take on a hard job.","I'd like an easy job please.").also { stage++ }
301 -> end().also{ when (buttonId) {
1 -> getJob(GnomeTipper.LEVEL.HARD)
2 -> getJob(GnomeTipper.LEVEL.EASY)
}}
1000 -> end()
else -> player("Uhhhh, good.").also { stage = 1000 }
}
return true
}
override fun getIds(): IntArray {
return intArrayOf(850)
}
private fun getJob(level: GnomeTipper.LEVEL){
if(!player.inventory.containsItem(ALUFT_ALOFT_BOX) && !player.bank.containsItem(ALUFT_ALOFT_BOX)){
player.inventory.add(ALUFT_ALOFT_BOX)
}
if(player.getAttribute("$GC_BASE_ATTRIBUTE:$GC_JOB_ORDINAL",-1) != -1){
player.dialogueInterpreter.sendDialogue("You already have a job.")
} else {
GlobalScope.launch {
var job = GnomeCookingJob.values().random()
while (job.level != level) {
job = GnomeCookingJob.values().random()
}
val item = Item(gnomeItems.random())
player.setAttribute("$GC_BASE_ATTRIBUTE:$GC_JOB_ORDINAL", job.ordinal)
player.setAttribute("$GC_BASE_ATTRIBUTE:$GC_NEEDED_ITEM", item)
player.dialogueInterpreter.sendDialogue("I need to deliver a ${item.name.toLowerCase()} to ${NPC(job.npc_id).name.toLowerCase()},", "who is ${job.tip}")
GameWorld.Pulser.submit(GnomeRestaurantPulse(player, if (level == GnomeTipper.LEVEL.HARD) 11L else 6L))
}
}
}
internal class GnomeRestaurantPulse(val player: Player,val minutes: Long): Pulse(){
var endTime = 0L
var timerMsgSent = false
init {
endTime = System.currentTimeMillis() + TimeUnit.MINUTES.toMillis(minutes)
}
override fun pulse(): Boolean{
val isComplete = player.getAttribute("$GC_BASE_ATTRIBUTE:$GC_JOB_ORDINAL",-1) == -1
val minsLeft = TimeUnit.MILLISECONDS.toMinutes(endTime - System.currentTimeMillis())
if(minsLeft % 2L == 0L && !timerMsgSent){
timerMsgSent = true
player.sendMessage(colorize("%RYou have $minsLeft minutes remaining on your job."))
} else if(minsLeft % 2L != 0L) {
timerMsgSent = false
}
if(System.currentTimeMillis() >= endTime){
player.sendMessage(colorize("%RYou have run out of time and your job has expired."))
player.removeAttribute("$GC_BASE_ATTRIBUTE:$GC_JOB_ORDINAL")
player.removeAttribute("$GC_BASE_ATTRIBUTE:$GC_JOB_COMPLETE")
player.removeAttribute("$GC_BASE_ATTRIBUTE:$GC_NEEDED_ITEM")
return true
}
return isComplete
}
}
}
@@ -1,59 +0,0 @@
package core.game.content.dialogue
import core.game.component.Component
import core.game.node.entity.npc.NPC
import core.game.node.entity.player.Player
import core.plugin.Initializable
import core.tools.Components
/**
* Dialogue for Asyff, the fancy dress shop owner
* @author Ceikry
*/
@Initializable
class AsyffDialogue(player: Player? = null) : DialoguePlugin(player){
override fun handle(interfaceId: Int, buttonId: Int): Boolean {
when(stage){
0 -> player(FacialExpression.ASKING,"Err...what are you saying exactly?").also { stage++ }
1 -> npc(FacialExpression.LAUGH,"I'm just saying that perhaps you would","like to peruse my selection of garments.").also { stage++ }
2 -> npc(FacialExpression.LAUGH,"Or, if that doesn't interest you, then maybe you have","something else to offer? I'm always on the look out","for interesting or unusual new materials.").also { stage++ }
3 -> options("Okay, let's see what you've got then.","Can you make clothing suitable for hunting in?","I think I might just leave the perusing for now thanks.","What sort of unusual materials did you have in mind?").also { stage++ }
4 -> when(buttonId){
1 -> player("Okay, let's see what you've got then.").also { stage = 10 }
2 -> player("Can you make clothing suitable for hunting?").also { stage = 20 }
3 -> player("I think I might just leave the perusing for now, thanks.").also { stage = 30 }
4 -> player("What sort of unusual materials did you have in mind?").also { stage = 40 }
}
//Okay, let's see what you've got then
10 -> end().also { npc.openShop(player) }
//Can you make clothing suitable for hunting
20 -> end().also { player.interfaceManager.open(Component(Components.custom_fur_clothing_477)) }//Open custom fur clothing interface
//I think I might just leave the perusing for now, thanks.
30 -> end()
//What sort of unusual materials do you have in mind?
40 -> npc("Well, some more colourful feathers might be useful.","For some surreal reason, all I normally seem to get offered","are large quantities of rather beaten up chicken feathers.").also { stage++ }
41 -> npc("People must have some very strange pastimes around","these parts, that's all I can say.").also { stage++ }
42 -> player("Ok, let's see what you've got then.").also { stage = 10 }
}
return true
}
override fun open(vararg args: Any?): Boolean {
npc = args[0] as NPC
npc(FacialExpression.HAPPY,"Now you look like someone who goes to","a lot of fancy dress parties.")
stage = 0
return true
}
override fun newInstance(player: Player?): DialoguePlugin {
return AsyffDialogue(player)
}
override fun getIds(): IntArray {
return intArrayOf(554)
}
}
@@ -1,91 +0,0 @@
package core.game.content.dialogue
import core.game.node.entity.player.Player
import core.game.node.item.Item
import core.plugin.Initializable
import core.tools.Items
import core.game.content.activity.gnomecooking.GC_BASE_ATTRIBUTE
import core.game.content.activity.gnomecooking.GC_TUT_FIN
import core.game.content.activity.gnomecooking.GC_TUT_PROG
@Initializable
class BlurberryDialogue(player: Player? = null): DialoguePlugin(player) {
var tutorialProgress = -1
var tutorialComplete = false
override fun newInstance(player: Player?): DialoguePlugin {
return BlurberryDialogue(player)
}
override fun open(vararg args: Any?): Boolean {
tutorialComplete = player.getAttribute("$GC_BASE_ATTRIBUTE:$GC_TUT_FIN",false)
tutorialProgress = player.getAttribute("$GC_BASE_ATTRIBUTE:$GC_TUT_PROG",-1)
if(tutorialProgress == 18){
npc("Yes, you, Aluft said you would be coming.")
stage = 0
return true
}
if(tutorialComplete){
npc("I do hope you're enjoying your work!")
stage = 1000
return true
}
npc("Hello, have you made that drink for me?")
stage = tutorialProgress
return true
}
override fun handle(interfaceId: Int, buttonId: Int): Boolean {
when(stage){
0 -> player("Yes! What is it I need to do?").also { stage++ }
1 -> npc("Well, I'd like to show you how to make","a drink.").also { stage++ }
2 -> player("Woah, sounds like fun!").also{ stage++ }
3 -> npc("Alright, then, let's get to it!").also { stage++ }
4 -> npc("I want you to make me a fruit blast. Simple drink!").also{ stage++ }
5 -> npc("Here's everything you need.").also { stage++ }
6 -> {
end()
val items = arrayOf(Item(Items.KNIFE_946),Item(Items.COCKTAIL_SHAKER_2025),Item(Items.COCKTAIL_GLASS_2026),Item(Items.PINEAPPLE_2114),Item(Items.LEMON_2102,2), Item(Items.ORANGE_2108))
if(player.inventory.hasSpaceFor(*items)){
player.inventory.add(*items)
player.setAttribute("/save:$GC_BASE_ATTRIBUTE:$GC_TUT_PROG",20)
} else {
player.dialogueInterpreter.sendDialogue("You don't have enough room for the items.")
}
}
20 -> {
if(player.inventory.containsItem(Item(Items.FRUIT_BLAST_9514))){
player("Yes, yes I have! Here you go.").also { stage++ }
} else {
player("No I have not.").also { stage = 1000 }
}
}
21 -> {
player.dialogueInterpreter.sendDialogue("You hand over the fruit blast.")
player.inventory.remove(Item(Items.FRUIT_BLAST_9514))
player.setAttribute("/save:$GC_BASE_ATTRIBUTE:$GC_TUT_PROG",22)
stage++
}
22 -> npc("Excellent, I think you're ready to go on the job!").also { stage++ }
23 -> {
npc("Go back and speak with Aluft now.")
player.setAttribute("/save:$GC_BASE_ATTRIBUTE:$GC_TUT_FIN",true)
stage = 1000
}
1000 -> end()
}
return true
}
override fun getIds(): IntArray {
return intArrayOf(848)
}
}
@@ -1,93 +0,0 @@
package core.game.content.dialogue
import core.game.component.Component
import core.game.node.entity.player.Player
import core.game.node.item.Item
import core.plugin.Initializable
import core.tools.Items
@Initializable
/**
* Handles Boriss' dialogue
* @author Ceikry
*/
class BrotherBordissDialogue(player: Player? = null) : DialoguePlugin(player) {
override fun newInstance(player: Player?): DialoguePlugin {
return BrotherBordissDialogue(player)
}
override fun npc(vararg messages: String?): Component {
return npc(FacialExpression.OLD_NORMAL,*messages)
}
override fun open(vararg args: Any?): Boolean {
player ?: return false
if(getSigil(player) != null && player.inventory.contains(Items.BLESSED_SPIRIT_SHIELD_13736,1)){
player("Can you combine my shield and sigil for me?")
stage = 10
return true
}
npc("Lovely day, adventurer.")
stage = 1000
return true
}
override fun handle(interfaceId: Int, buttonId: Int): Boolean {
when(stage){
10 -> npc("I certainly can, for the price of","1,500,000 coins.").also { stage++ }
11 -> options("Okay, sounds great!","No, thanks.").also { stage++ }
12 -> when(buttonId){
1 -> if(player.inventory.contains(995,1500000)){
player("Okay, sounds great!")
stage = 15
} else {
player("I'd like to, but I don't have the coin.")
stage++
}
2 -> player("No, thanks").also { stage = 1000 }
}
13 -> npc("That's a shame, then.").also { stage = 1000 }
15 -> {
npc("Lovely, here you are.")
val sigil = getSigil(player)
if(sigil == null){
end()
return true
}
if(player.inventory.remove(sigil,Item(995,1500000),Item(Items.BLESSED_SPIRIT_SHIELD_13736))){
player.inventory.add(getShield(player,sigil))
}
stage++
}
16 -> player("Thank you!").also { stage = 1000 }
1000 -> end()
}
return true
}
override fun getIds(): IntArray {
return intArrayOf(7724)
}
fun getSigil(player: Player): Item?{
for(sigil in arrayOf(Items.ARCANE_SIGIL_13746,Items.DIVINE_SIGIL_13748,Items.SPECTRAL_SIGIL_13752,Items.ELYSIAN_SIGIL_13750)){
if(player.inventory.contains(sigil,1)) return Item(sigil)
}
return null
}
fun getShield(player: Player, sigil: Item): Item?{
return when(sigil.id){
Items.ARCANE_SIGIL_13746 -> Item(Items.ARCANE_SPIRIT_SHIELD_13738)
Items.ELYSIAN_SIGIL_13750 -> Item(Items.ELYSIAN_SPIRIT_SHIELD_13742)
Items.DIVINE_SIGIL_13748 -> Item(Items.DIVINE_SPIRIT_SHIELD_13740)
Items.SPECTRAL_SIGIL_13752 -> Item(Items.SPECTRAL_SPIRIT_SHIELD_13744)
else -> null
}
}
}
@@ -1,103 +0,0 @@
package core.game.content.dialogue
import core.game.component.Component
import core.game.node.entity.Entity
import core.game.node.entity.npc.NPC
import core.game.node.entity.player.Player
import core.tools.START_DIALOGUE
abstract class DialogueFile {
var player: Player? = null
var npc: NPC? = null
var interpreter: DialogueInterpreter? = null
open var stage = START_DIALOGUE
var dialoguePlugin: DialoguePlugin? = null
abstract fun handle(componentID: Int, buttonID: Int)
fun load(player: Player, npc: NPC?, interpreter: DialogueInterpreter): DialogueFile{
this.player = player
this.npc = npc
this.interpreter = interpreter
return this
}
open fun npc(vararg messages: String?): Component? {
return if (npc == null) {
interpreter!!.sendDialogues(
npc!!.id,
if (npc!!.id > 8591) FacialExpression.OLD_NORMAL else FacialExpression.FRIENDLY,
*messages
)
} else interpreter!!.sendDialogues(
npc,
if (npc!!.id > 8591) FacialExpression.OLD_NORMAL else FacialExpression.FRIENDLY,
*messages
)
}
open fun npc(id: Int, vararg messages: String?): Component? {
return interpreter!!.sendDialogues(id, FacialExpression.FRIENDLY, *messages)
}
open fun npc(expression: FacialExpression?, vararg messages: String?): Component? {
return if (npc == null) {
interpreter!!.sendDialogues(0, expression, *messages)
} else interpreter!!.sendDialogues(npc, expression, *messages)
}
open fun player(vararg messages: String?): Component? {
return interpreter!!.sendDialogues(player, null, *messages)
}
open fun player(expression: FacialExpression?, vararg messages: String?): Component? {
return interpreter!!.sendDialogues(player, expression, *messages)
}
fun end(){
if(interpreter != null) interpreter!!.close()
}
open fun sendNormalDialogue(entity: Entity?, expression: FacialExpression?, vararg messages: String?) {
interpreter!!.sendDialogues(entity, expression, *messages)
}
open fun options(vararg options: String?) {
interpreter!!.sendOptions("Select an Option", *options)
}
/**
* Use in place of setting the stage to END_DIALOGUE when you want to return to the default dialogue plugin at START_DIALOGUE
*/
fun endFile(){
interpreter!!.dialogue.file = null
}
/**
* Return to the default dialogue plugin at the given stage.
* Should be used in place of setting a new stage. I.E. instead of "stage = END_DIALOGUE" use "returnAtStage(whatever stage)"
* @param stage The stage to return to.
*/
fun returnAtStage(toStage: Int){
dialoguePlugin!!.file = null
dialoguePlugin!!.stage = toStage
}
/**
* Use when you've entered a DialogueFile but current state does not match any possible conditionals.
* Sort-of a fail-safe in a sense.
*/
fun abandonFile(){
interpreter!!.dialogue.file = null
player("Huh. Nevermind.")
}
open fun getCurrentStage(): Int{
return stage
}
fun Int.substage(stage: Int): Int{
return this + stage
}
}
@@ -1,92 +0,0 @@
package core.game.content.dialogue
import core.game.content.dialogue.DialoguePlugin
import core.game.content.quest.free.dragonslayer.DragonSlayer
import core.game.content.quest.free.dragonslayer.DukeHoracioDSDialogue
import core.game.content.quest.members.thelosttribe.DukeHoracioTLTDialogue
import core.game.content.dialogue.FacialExpression
import core.game.node.entity.player.link.diary.DiaryType
import core.game.node.entity.player.link.quest.Quest
import core.game.content.quest.free.runemysteries.DukeHoracioRMDialogue
import core.game.content.dialogue.DukeHoracioDialogue
import core.game.node.entity.npc.NPC
import core.game.node.entity.player.Player
import core.game.node.item.Item
import core.tools.DIALOGUE_INITIAL_OPTIONS_HANDLE
import core.tools.END_DIALOGUE
/**
* Core dialogue plugin for Duke Horacio, redirects to more specific DialogueFiles.
* @author Ceikry
*/
class DukeHoracioDialogue(player: Player? = null) : DialoguePlugin(player) {
override fun getIds(): IntArray {
return intArrayOf(741)
}
override fun open(vararg args: Any): Boolean {
npc = args[0] as NPC
if (player.questRepository.getQuest("Dragon Slayer").getStage(player) == 100 && !player.inventory.containsItem(DragonSlayer.SHIELD) && !player.bank.containsItem(DragonSlayer.SHIELD) || !player.questRepository.getQuest("Dragon Slayer").isStarted(player) && !player.questRepository.getQuest("Dragon Slayer").isCompleted(player)) {
addOption("Dragon Slayer", DukeHoracioDSDialogue(player.questRepository.getStage("Dragon Slayer")))
}
if (!player.questRepository.isComplete("Lost Tribe") && player.questRepository.getQuest("Lost Tribe").isStarted(player)) {
addOption("Lost Tribe", DukeHoracioTLTDialogue(player.questRepository.getStage("Lost Tribe")))
}
if (!sendChoices()) {
interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Greetings. Welcome to my castle.")
}
stage = 0
// Speak to the Duke of Lumbridge
player.achievementDiaryManager.finishTask(player, DiaryType.LUMBRIDGE, 0, 2)
return true
}
override fun handle(interfaceId: Int, buttonId: Int): Boolean {
when (stage) {
DIALOGUE_INITIAL_OPTIONS_HANDLE -> {
npc("Greetings. Welcome to my castle.")
loadFile(optionFiles[buttonId - 1])
}
0 -> {
interpreter.sendOptions("Select an Option", "Have you any quests for me?", "Where can I find money?")
stage = 1
}
1 -> when (buttonId) {
1 -> {
interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Have any quests for me?")
stage = 20
}
2 -> {
interpreter.sendDialogues(
npc,
FacialExpression.HALF_GUILTY,
"I hear many of the local people earn money by learning a",
"skill. Many people get by in life by becoming accomplished",
"smiths, cooks, miners and woodcutters."
)
stage = END_DIALOGUE
}
}
20 -> {
npc("Let me see...")
if (!player.questRepository.isComplete("Rune Mysteries")) {
loadFile(DukeHoracioRMDialogue(player.questRepository.getStage("Rune Mysteries")))
} else {
stage++
}
}
21 -> {
npc("Nope, I've got everything under control", "in the castle at the moment.")
stage = END_DIALOGUE
}
}
return true
}
override fun newInstance(player: Player): DialoguePlugin {
return DukeHoracioDialogue(player)
}
}
@@ -1,97 +0,0 @@
package core.game.content.dialogue
import core.tools.Items
import core.game.node.entity.player.Player
import core.game.node.entity.player.link.diary.DiaryType
import core.game.node.item.Item
import core.plugin.Initializable
/**
* Elsie
* @author afaroutdude
*/
@Initializable
class ElsieDialogue(player: Player? = null) : DialoguePlugin(player) {
override fun open(vararg args: Any?): Boolean {
when (player.inventory.containsAtLeastOneItem(Items.CUP_OF_TEA_712)) {
true -> npc("Ooh - that looks like a lovely cup of tea, dearie. Is it for", "me?").also { stage = 100 }
false -> npc("Hello dearie! What can old Elsie do for you?").also { stage = 10 }
}
return true
}
override fun handle(interfaceId: Int, buttonId: Int): Boolean {
when (stage) {
999 -> end()
10 -> interpreter.sendOptions("What would you like to say?", "What are you making?", "Can you tell me a story?", "Can you tell me how to get rich?").also { stage++ }
11 ->
when (buttonId) {
1 -> player("What are you making?").also { stage = 20 }
2 -> player("Can you tell me a story?").also { stage = 30 }
3 -> player("Can you tell me how to get rich?").also { stage = 40 }
}
20 -> player("What are you making?").also { stage++ }
21 -> npc("I'm knitting a new stole for Father Lawrence", "downstairs. He could do with something to keep his", "neck warm, standing in that draughty old church", "all day.").also { stage++ }
22 -> interpreter.sendOptions("What would you like to say?", "Can you tell me a story?", "Can you tell me how to get rich?").also { stage++ }
23 ->
when (buttonId) {
1 -> player("Can you tell me a story?").also { stage = 30 }
2 -> player("Can you tell me how to get rich?").also { stage = 40 }
}
30 -> player("Can you tell me a story?").also { stage++ }
31 -> npc("Maybe I could tell you a story if you'd fetch me", "a nice cup of tea.").also { stage++ }
32 -> player("I'll think about it.").also { stage == 999 }
40 -> player("Can you tell me how to get rich??").also { stage++ }
41 -> npc("Well, dearie, I'm probably not the best person to ask about money, but I think the best thing would be for you to get a good trade. If you've got a trade you can earn your way, that's what my old father told me,").also { stage++ }
42 -> npc("Saradomin rest his soul. I hear people try to get rich by fighting in the Wilderness north of here or the Duel Arena in the south, but that's no way for honest folks to earn a living! So get yourself a good trade, and keep").also { stage++ }
43 -> npc("working at it. There's always folks wanting to buy ore and food around here.").also { stage++ }
44 -> player("Thanks, old woman.").also { stage++ }
45 -> interpreter.sendOptions("What would you like to say?", "What are you making?", "Can you tell me a story?").also { stage++ }
46 ->
when (buttonId) {
1 -> player("What are you making?").also { stage = 20 }
2 -> player("Can you tell me a story?").also { stage = 30 }
}
100 -> interpreter.sendOptions("What would you like to say?", "Yes, you can have it.", "No, keep your hands off my tea.").also { stage++ }
101 ->
when (buttonId) {
1 -> player("Yes, you can have it.").also { stage++ }
2 -> player("No, keep your hands off my tea.").also { stage = 120 }
}
102 -> player("Yes, you can have it.").also { stage++ }
103 -> npc("Ahh, there's nothing like a nice cuppa tea. I know what,", "I'll tell you a story to thank you for the lovely tea...").also {
player.inventory.remove(Item(Items.CUP_OF_TEA_712))
player.achievementDiaryManager.finishTask(player, DiaryType.VARROCK, 0, 14)
stage++
}
104 -> npc("A long time ago, when I was a little girl, there was a", "handsome young man living in Varrock. I saw him here", "in the church quite often. Everyone said he was going", "to become a priest, and we girls were so sad about that.").also { stage++ }
105 -> npc("But young Dissy - that was the young man's nickname", "- he was a wild young thing. One night he gathered", "some lads together, and after the evening prayer-", "meeting they all put on masks and sneaked down to the").also { stage++ }
106 -> npc("evil temple in the south of the city, the evil one. The", "next day, there was quite a hubbub. The guards told us", "that someone had painted 'Saradomin pwns' on the wall", "of the Zamorakian temple!").also { stage++ }
107 -> npc("Now, we'd always been taught to keep well away from", "that dreadful place, but it really did us all good to see", "someone wasn't afraid of the scum who live at that end", "of town. Old Father Packett was furious, but Dissy just").also { stage++ }
108 -> npc("laughed it off.").also { stage++ }
109 -> npc("Dissy left town after that, saying he wanted to see the", "world. It was such a shame, he had the most handsome", "shoulders...").also { stage++ }
110 -> npc("A young man came here looking for stories about Dissy", "- of course, that's not his proper name, but his friends", "called him Dissy - and I told him that one. He said", "Dissy had become a really famous man and there was").also { stage++ }
111 -> npc("going to be a book about him. Well, that's all good, but I", "do wish Dissy had just come back to Varrock. I did", "miss him so much... well, until I met my Freddie and", "we got married, but that's another story.").also { stage++ }
112 -> player("Thank you. I'll leave you to your knitting now.").also { stage = 999 }
120 -> npc("Aww. Maybe another time. Anyway, what can old Elsie do for you?").also { stage++ }
121 ->
when (buttonId) {
1 -> player("What are you making?").also { stage = 20 }
2 -> player("Can you tell me a story?").also { stage = 122 }
}
122 -> npc("Well, maybe I could tell a story if you'd give me that lovely cup of tea you've got there.").also { stage = 100 }
}
return true;
}
override fun newInstance(player: Player?): DialoguePlugin {
return ElsieDialogue(player)
}
override fun getIds(): IntArray {
return intArrayOf(5915)
}
}
@@ -1,30 +0,0 @@
package core.game.content.dialogue
import core.game.node.entity.npc.NPC
import core.game.node.entity.player.Player
import core.tools.START_DIALOGUE
class EmptyPlugin(player: Player? = null,val file: DialogueFile?) : DialoguePlugin(player) {
override fun newInstance(player: Player?): DialoguePlugin {
return EmptyPlugin(player,null)
}
override fun open(vararg args: Any?): Boolean {
if(args.isNotEmpty() && args[0] is NPC){
npc = args[0] as NPC
}
stage = START_DIALOGUE
loadFile(file)
interpreter.handle(0,0)
return true
}
override fun handle(interfaceId: Int, buttonId: Int): Boolean {
return true
}
override fun getIds(): IntArray {
return intArrayOf(Integer.MAX_VALUE)
}
}
@@ -1,138 +0,0 @@
package core.game.content.dialogue
import com.sun.org.apache.xpath.internal.operations.Bool
import core.cache.def.impl.NPCDefinition
import core.cache.def.impl.ObjectDefinition
import core.game.content.global.shop.Shop
import core.game.node.entity.npc.NPC
import core.game.node.entity.player.Player
import core.game.system.config.ShopParser
import core.game.system.config.ShopParser.Companion.SHOPS
import core.plugin.Initializable
import core.plugin.Plugin
/**
* Dialogue for Gabooty
* @author qmqz
*/
@Initializable
class GabootyDialogue(player: Player? = null) : DialoguePlugin(player){
override fun open(vararg args: Any?): Boolean {
npc = args[0] as NPC
player(FacialExpression.FRIENDLY, "What do you do here?").also { stage = 0 }
return true
}
override fun handle(interfaceId: Int, buttonId: Int): Boolean {
when(stage){
0 -> npc(FacialExpression.FRIENDLY,"Not much really... I run a local shop which earns", "me a few trading sticks, but that's about it.", "I keep myself to myself really.").also { stage++ }
1 -> player(FacialExpression.FRIENDLY, "What are trading sticks?").also { stage++ }
2 -> npc(FacialExpression.FRIENDLY,
"They're the local currency Bwana, ",
"it's used in Tai Bwo Wannai, there's usually",
"some odd jobs that need doing around the village",
"which you could do to earn some trading sticks.").also { stage++ }
3 -> npc(FacialExpression.FRIENDLY,
"Or, if you have something which the local villagers",
"might like, you could sell it to me and I'll pay",
"you for it in trading sticks.").also { stage++ }
4 -> interpreter.sendOptions("Select an Option",
"What sort of things do the local villagers like?",
"You run a shop?",
"I want to ask another question.",
"Ok, thanks.").also { stage++ }
5 ->
when (buttonId) {
1 -> player("What sort of things do the local villagers like?").also { stage = 10 }
2 -> player("You run a shop?").also { stage = 21 }
3 -> player("I want to ask another question.").also { stage = 23 }
4 -> player("Ok, thanks.").also { stage = 99 }
}
10 -> npc(FacialExpression.FRIENDLY,
"Gnome cocktails! It's amazing but we all just love them!",
"Luckily I've managed to get stocks of the gnome made",
"cocktails and I supply those to my favourite customers.",
"However, many of the customers really like the cocktails").also { stage++ }
11 -> npc(FacialExpression.FRIENDLY,
"made by the adventurers passing through this way.",
"If you ever happen to have any, bring them my way! ",
"I'll give you a good deal on it that's for sure!").also { stage++ }
12 -> player(FacialExpression.FRIENDLY, "How did the villagers ever get to try any gnome cocktails?").also { stage++ }
13 -> npc(FacialExpression.FRIENDLY,
"I think it was that gnome pilot who crashed his glider,",
"perhaps he had a little mini-bar on board?",
"Come to think about it, you'd expect the little guy to get ",
"his stuff together and move on out of here wouldn't you?").also { stage++ }
14 -> npc(FacialExpression.FRIENDLY, "He must love the jungle to have stayed here so long!").also { stage = 4 }
21 -> npc(FacialExpression.FRIENDLY,
"Yes, it's the Tai Bwo cooperative... catchy name huh!",
"We sell a few local village trinkets and tools.",
"Also, there are a few items that we're actually",
"looking to stock for the locals' sake.").also { stage++ }
22 -> npc(FacialExpression.FRIENDLY,
"If you happen across any of them please bring them to me,",
"I'll pay a good price for them.",
"I'm sure you'll find the prices very reasonable.").also { stage++ }
23 -> interpreter.sendOptions("Select an Option",
"What are trading sticks?",
"You run a shop?",
"Can I take a look at what you have to sell?",
"Why do you only take one sort of Gnome cocktail?",
"I want to ask another question.").also { stage++ }
24 ->
when (buttonId) {
1 -> player("What are trading sticks?").also { stage = 2 }
2 -> player("You run a shop?").also { stage = 21 }
3 -> player("Can I take a look at what you have to sell?").also { stage = 30 }
4 -> player("Why do you only take one sort of Gnome cocktail?").also { stage = 40 }
5 -> player("I want to ask another question.").also { stage = 4 }
}
30 -> npc(FacialExpression.FRIENDLY, "Sure you can...which shop would you like to see?",
"The Cooperative or Drinks store?").also { stage++ }
31 ->interpreter.sendOptions("Select an Option",
"The Cooperative",
"The Drinks Store",
"None thanks...").also { stage++ }
32 ->
when (buttonId) { //gotta add shops
1 -> player("The Cooperative").also { stage = 90 }
2 -> player("The Drinks Store").also { stage = 91 }
3 -> player("None thanks...").also { stage = 99 }
}
40 -> npc(FacialExpression.FRIENDLY, "It's funny that, actually. I've managed to get a ",
"good deal with the pilot of that gnome glider. He can supply",
"me directly now. However, it's really interesting that the ",
"local villagers really like the gnome cocktails made by the").also { stage++ }
41 -> npc(FacialExpression.FRIENDLY, "adventurers passing through this way.").also { stage++ }
42 -> player(FacialExpression.FRIENDLY, "Why, what's the difference?").also { stage++ }
43 -> npc(FacialExpression.FRIENDLY, "I think it may just be that they're made fresher,",
"or there is a slight twist in the flavour of the drink,",
"you know, a little more of this, a little less of that, it all",
"adds up and makes for an interesting tipple!").also { stage = 23 }
90 -> end().also { ShopParser.Companion.openUid(player,226) }
91 -> end().also { ShopParser.Companion.openUid(player,227) }
99 -> end()
}
return true
}
override fun newInstance(player: Player?): DialoguePlugin {
return GabootyDialogue(player)
}
override fun getIds(): IntArray {
return intArrayOf(2519, 2520, 2521)
}
}
@@ -1,77 +0,0 @@
package core.game.content.dialogue
import core.Util
import core.tools.Items
import core.game.node.entity.player.Player
import core.game.node.entity.player.link.diary.DiaryType
import core.game.node.item.Item
import core.plugin.Initializable
@Initializable
class GeoffreyDialogue(player: Player? = null) : DialoguePlugin(player) {
override fun open(vararg args: Any?): Boolean {
val diary = player.achievementDiaryManager.getDiary(DiaryType.SEERS_VILLAGE)
if (diary.levelRewarded.any()) {
player("Hello there. Are you Geoff-erm-Flax? I've been told that", "you'll give me some flax.")
// If 1 day has not passed since last flax reward
if (player.getAttribute("diary:seers:flax-timer", 0) > System.currentTimeMillis()) {
stage = 98
return true
}
// If player cannot receive flax reward
if (!player.inventory.hasSpaceFor(Item(Items.FLAX_1780, 1))) {
stage = 99
return true
}
// Determine flax reward by seers diary reward status
when (diary.reward) {
-1 -> stage = 999
0 -> stage = 100
1 -> stage = 101
2 -> stage = 102
}
} else {
player("Hello there. You look busy.")
stage = 0
}
return true
}
override fun newInstance(player: Player?): DialoguePlugin {
return GeoffreyDialogue(player)
}
override fun handle(interfaceId: Int, buttonId: Int): Boolean {
when (stage) {
999 -> end()
0 -> npc("Yes, I am very busy. Picking GLORIOUS flax.", "The GLORIOUS flax won't pick itself. So I pick it.", "I pick it all day long.").also { stage++ }
1 -> player("Wow, all that flax must really mount up. What do you do with it all?").also { stage++ }
2 -> npc("I give it away! I love picking the GLORIOUS flax,", "but, if I let it all mount up, I wouldn't have any", "room for more GLORIOUS flax.").also { stage++ }
3 -> player("So, you're just picking the flax for fun? You must", "really like flax.").also { stage++ }
4 -> npc("'Like' the flax? I don't just 'like' flax. The", "GLORIOUS flax is my calling, my reason to live.", "I just love the feeling of it in my hands!").also { stage++ }
5 -> player("Erm, okay. Maybe I can have some of your spare flax?").also { stage++ }
6 -> npc("No. I don't trust outsiders. Who knows what depraved", "things you would do with the GLORIOUS flax? Only", "locals know how to treat it right.").also { stage++ }
7 -> player("I know this area! It's, erm, Seers' Village. There's", "a pub and, er, a bank.").also { stage++ }
8 -> npc("Pah! You call that local knowledge? Perhaps if you", "were wearing some kind of item from one of the", "seers, I might trust you.").also { stage = 999 }
98 -> npc("I've already given you your GLORIOUS flax", "for the day. Come back tomorrow.").also { stage = 999 } // TODO find accurate dialogue
99 -> npc("Yes, but your inventory is full. Come back", "when you have some space for GLORIOUS flax.").also { stage = 999 } // TODO find accurate dialogue
100 -> {rewardFlax(30, "Yes. The seers have instructed me to give you an", "allowance of 30 GLORIOUS flax a day. I'm not going", "to argue with them, so here you go.")} // TODO find accurate dialogue
101 -> {rewardFlax(60, "Yes. Stankers has instructed me to give you an", "allowance of 60 GLORIOUS flax a day. I'm not going", "to argue with a dwarf, so here you go.")} // TODO find accurate dialogue
102 -> {rewardFlax(120, "Yes. Sir Kay has instructed me to give you an", "allowance of 120 GLORIOUS flax a day. I'm not going", "to argue with a knight, so here you go.")}
}
return true
}
fun rewardFlax(n: Int, vararg messages: String): Unit {
npc(*messages)
player.inventory.add(Item(Items.FLAX_1780, n))
player.setAttribute("/save:diary:seers:flax-timer", Util.nextMidnight(System.currentTimeMillis()))
stage = 999
}
override fun getIds(): IntArray {
return intArrayOf(8590)
}
}
@@ -1,32 +0,0 @@
package core.game.content.dialogue
import core.game.node.entity.player.Player
import core.plugin.Initializable
/**
* Iffie
* @author afaroutdude
*/
@Initializable
class IffieDialogue(player: Player? = null) : DialoguePlugin(player) {
override fun open(vararg args: Any?): Boolean {
npc("Sorry, dearie, if I stop to chat I'll lose count.", "Talk to my sister instead; she likes to chat.", "You'll find her upstairs in the church.")
stage = 999;
return true
}
override fun handle(interfaceId: Int, buttonId: Int): Boolean {
when (stage) {
999 -> end()
}
return true
}
override fun newInstance(player: Player?): DialoguePlugin {
return IffieDialogue(player)
}
override fun getIds(): IntArray {
return intArrayOf(5914)
}
}
@@ -1,86 +0,0 @@
package core.game.content.dialogue
import core.game.content.quest.members.allfiredup.KingRoaldAFUDialogue
import core.game.content.activity.allfiredup.KingRoaldAFUMiniDialogue
import core.game.content.quest.free.shieldofarrav.KingRoaldArravDialogue
import core.game.content.quest.members.priestinperil.KingRoaldPIPDialogue
import core.game.node.entity.npc.NPC
import core.game.node.entity.player.Player
import core.tools.DIALOGUE_INITIAL_OPTIONS_HANDLE
import core.tools.END_DIALOGUE
import core.tools.START_DIALOGUE
/**
* Central dialogue plugin for King Roald. Reroutes to the more specific DialogueFiles
* @author Ceikry
* @version 1.0
*/
class KingRoaldDialogue(player: Player? = null) : DialoguePlugin(player) {
override fun newInstance(player: Player): DialoguePlugin {
return KingRoaldDialogue(player)
}
override fun open(vararg args: Any): Boolean {
npc = args[0] as NPC
if (player.getAttribute("afu-mini:ring", false) || player.getAttribute("afu-mini:gloves", false) || player.getAttribute("afu-mini:adze", false)) {
player("Your Majesty! I did it!")
loadFile(KingRoaldAFUMiniDialogue())
return true
}
if(player.questRepository.isComplete("Priest in Peril")) {
if (!player.questRepository.hasStarted("All Fired Up") || player.questRepository.getQuest("All Fired Up").getStage(player) == 90) {
addOption("All Fired Up",KingRoaldAFUDialogue(player.questRepository.getStage("All Fired Up")))
}
} else {
addOption("Priest in Peril",KingRoaldPIPDialogue(player.questRepository.getStage("Priest in Peril")))
}
if (player.questRepository.getQuest("Shield of Arrav").isStarted(player) && !player.questRepository.getQuest("Shield of Arrav").isCompleted(player)) {
addOption("Shield of Arrav",KingRoaldArravDialogue())
}
if(!sendChoices()){
player("Greetings, your Majesty.")
}
return true
}
override fun handle(interfaceId: Int, buttonId: Int): Boolean {
//Default (non-specific) dialogue
when (stage) {
DIALOGUE_INITIAL_OPTIONS_HANDLE -> {
player("Greetings, your Majesty.")
loadFile(optionFiles[buttonId - 1])
}
START_DIALOGUE -> {
interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Do you have anything of importance to say?")
stage = 1
}
1 -> {
interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "...Not really.")
stage = 2
}
2 -> {
interpreter.sendDialogues(
npc,
FacialExpression.HALF_GUILTY,
"You will have to excuse me, then. I am very busy as I",
"have a kingdom to run!"
)
stage = END_DIALOGUE
}
END_DIALOGUE -> end()
}
return true
}
override fun getIds(): IntArray {
return intArrayOf(648, 2590, 5838)
}
}
@@ -1,45 +0,0 @@
package core.game.content.dialogue
import core.game.node.entity.npc.NPC
import core.game.node.entity.player.Player
import core.plugin.Initializable
/**
* Dialogue for Legends Guards at the Legends Guild
* @author qmqz
*/
@Initializable
class LegendsGuardDialogue(player: Player? = null) : DialoguePlugin(player){
fun gender (male : String = "sir", female : String = "madam") = if (player.isMale) male else female
override fun open(vararg args: Any?): Boolean {
npc = args[0] as NPC
npc(FacialExpression.FRIENDLY,"! ! ! Attention ! ! !")
stage = 0
return true
}
override fun handle(interfaceId: Int, buttonId: Int): Boolean {
when(stage){
0 -> npc(FacialExpression.FRIENDLY,"Legends Guild Member Approaching").also { stage++ }
1 -> npc(FacialExpression.FRIENDLY,"Welcome "+ gender() + "!", "I hope you enjoy your time in the Legends Guild.").also { stage = 99 }
//while doing legend's quest
10 -> npc(FacialExpression.FRIENDLY,"I hope the quest is going well " + gender() + ".").also { stage = 99 }
//after the legend's quest is done
20 -> npc(FacialExpression.FRIENDLY,"Legends Guild Member Approaching!").also { stage = 99 }
99 -> end()
}
return true
}
override fun newInstance(player: Player?): DialoguePlugin {
return LegendsGuardDialogue(player)
}
override fun getIds(): IntArray {
return intArrayOf(398, 399)
}
}
@@ -1,39 +0,0 @@
package core.game.content.dialogue
import core.game.node.entity.npc.NPC
import core.game.node.entity.player.Player
import core.plugin.Initializable
/**
* Dialogue for Lensa on Jaitizso
* @author qmqz
*/
@Initializable
class LensaDialogue(player: Player? = null) : DialoguePlugin(player){
fun gender (male : String = "brother", female : String = "sister") = if (player.isMale) male else female
override fun open(vararg args: Any?): Boolean {
npc = args[0] as NPC
player(FacialExpression.FRIENDLY,"Hello.")
stage = 0
return true
}
//should say [Fremennik name] after gender, but this is not yet implemented
override fun handle(interfaceId: Int, buttonId: Int): Boolean {
when(stage){
0 -> npc(FacialExpression.FURIOUS,"My apologies " + gender() + "!", "I have not time to tarry here with you!").also { stage++ }
1 -> player(FacialExpression.AFRAID,"That's okay, I didn't really want anything.").also { stage = 99 }
99 -> end()
}
return true
}
override fun newInstance(player: Player?): DialoguePlugin {
return LensaDialogue(player)
}
override fun getIds(): IntArray {
return intArrayOf(5494)
}
}
@@ -1,72 +0,0 @@
package core.game.content.dialogue
import core.game.component.Component
import core.game.node.entity.player.Player
import core.plugin.Initializable
import core.game.content.activity.ActivityManager
import core.game.content.quest.members.thelosttribe.GoblinFollower
import core.game.content.quest.members.thelosttribe.MistagLTDialogue
import core.tools.END_DIALOGUE
import core.tools.START_DIALOGUE
@Initializable
class MistagDialogue (player: Player? = null) : DialoguePlugin(player){
override fun newInstance(player: Player?): DialoguePlugin {
return MistagDialogue(player)
}
override fun npc(vararg messages: String?): Component {
return npc(FacialExpression.OLD_NORMAL,*messages)
}
override fun open(vararg args: Any?): Boolean {
val ltStage = player.questRepository.getStage("Lost Tribe")
if(args.size > 0 && args[0] == "greeting"){
npc("A human knows ancient greeting?")
loadFile(MistagLTDialogue(true,ltStage))
return true
}
if(!player.getAttribute("mistag-greeted",false)){
npc("Who...who are you? How did you get in here?")
stage = -100
return true
}
if(ltStage == 45){
npc("Greetings, friend. I am sorry I panicked when I saw you.")
loadFile(MistagLTDialogue(false,ltStage))
return true
} else if(ltStage == 50){
npc("Hello, friend?")
loadFile(MistagLTDialogue(false,ltStage))
return true
}
npc("Hello friend!").also { stage = 0 }
return true
}
override fun handle(interfaceId: Int, buttonId: Int): Boolean {
when(stage){
//Pre-greeting
-100 -> npc("Help! A surface dweller this deep in our mines? We will","all be destroyed!").also { stage++ }
-99 -> end()
//Normal Dialogue
START_DIALOGUE -> options("May I mine the rocks here?","Can you show me the way out?").also { stage++ }
1 -> when(buttonId){
1 -> player("May I mine the rocks here?").also { stage = 10 }
2 -> player("Can you show me the way out of the mine?").also { stage = 20 }
}
10 -> npc("Certainly, friend!").also { stage = END_DIALOGUE }
20 -> npc("Certainly!").also { GoblinFollower.sendToLumbridge(player); stage = END_DIALOGUE }
}
return true
}
override fun getIds(): IntArray {
return intArrayOf(2084)
}
}
@@ -1,100 +0,0 @@
package core.game.content.dialogue
import core.game.node.entity.npc.NPC
import core.game.node.entity.player.Player
import core.game.node.item.Item
import core.plugin.Initializable
/**
* Represents the dialogue plugin used for Otto
* @author Splinter
* @version 1.0
*/
@Initializable
class OttoGodblessedDialogue(player: Player? = null) : DialoguePlugin(player) {
override fun newInstance(player: Player): DialoguePlugin {
return OttoGodblessedDialogue(player)
}
override fun open(vararg args: Any?): Boolean {
npc = args[0] as NPC
npc("Good day, you seem a hearty warrior. Maybe even", "some barbarian blood in that body of yours?")
stage = -1
return true
}
override fun init() {
super.init()
}
override fun handle(interfaceId: Int, buttonId: Int): Boolean {
when (stage) {
-1 -> options("Ask about hastas","Ask about barbarian training").also { stage++ }
0 -> when(buttonId){
1 -> player("Can you help me with Zamorakian weapons?").also { stage++ }
2 -> player("Is there anything you can teach me?").also { stage = 20 }
}
1 -> {
npc("Yes, I can convert a Zamorakian spear into a hasta.", "The spirits require me to request 300,000 coins from", "you for this service.")
stage = 2
}
2 -> {
interpreter.sendOptions("Select an Option", "Spear into hasta", "Hasta back to spear")
stage = 3
}
3 -> when (buttonId) {
1 -> if (player.inventory.contains(11716, 1) && player.inventory.contains(995, 300000)) {
interpreter.sendOptions("Convert your spear?", "Yes", "No")
stage = 4
} else {
player.sendMessage("You need a Zamorakian Spear and 300,000 coins to proceed.")
end()
}
2 -> if (player.inventory.contains(14662, 1)) {
interpreter.sendOptions("Revert back to spear?", "Yes", "No")
stage = 5
} else {
player.sendMessage("You need a Zamorakian Hasta to proceed.")
end()
}
}
4 -> when (buttonId) {
1 -> if (player.inventory.remove(Item(11716, 1), Item(995, 300000))) {
player.inventory.add(Item(14662))
interpreter.sendItemMessage(14662, "Otto converts your spear into a hasta.")
stage = 6
} else {
end()
}
2 -> end()
}
5 -> when (buttonId) {
1 -> if (player.inventory.remove(Item(14662, 1))) {
player.inventory.add(Item(11716))
interpreter.sendItemMessage(11716, "Otto converts your hasta back into a spear.")
stage = 6
} else {
end()
}
2 -> end()
}
6 -> end()
20 -> npc("I can teach you how to fish.").also { stage++ }
21 -> player("Oh, that's pretty underwhelming. But uhhh, okay!").also { stage++ }
22 -> npc("Alright so here's what you gotta do:","You need to grab a pole and some bait, and then","fling it into the water!").also { stage++ }
23 -> player("The whole pole?").also { stage++ }
24 -> npc(FacialExpression.ANGRY, "No, not the whole pole!").also { stage++ }
25 -> npc("Look, just... grab the pole under my bed","and go click on that fishing spot.").also { stage++ }
26 -> player(FacialExpression.ASKING,"...click?").also { stage++ }
27 -> npc(FacialExpression.FURIOUS, "JUST GO DO IT!").also { stage++; player.setAttribute("/save:barbtraining:fishing",true) }
28 -> end()
}
return true
}
override fun getIds(): IntArray {
return intArrayOf(2725)
}
}
@@ -1,339 +0,0 @@
package core.game.content.dialogue
import core.game.node.entity.player.Player
import core.game.node.item.Item
import core.net.packet.PacketRepository
import core.net.packet.context.ChildPositionContext
import core.net.packet.out.RepositionChild
import core.tools.Components
import core.tools.StringUtils
/**
* Represents a skill dialogue handler class.
* @author Vexia
*/
open class SkillDialogueHandler(
/**
* Represents the player.
*/
val player: Player,
/**
* Represents the skill dialogue type.
*/
val type: SkillDialogue?, vararg data: Any) {
/**
* Gets the player.
* @return The player.
*/
/**
* Gets the type.
* @return The type.
*/
/**
* Gets the passed data.
* @return the data.
*/
/**
* Represents the object data passed through.
*/
val data: Array<Any>
/**
* Method used to open a skill dialogue.
*/
fun open() {
player.dialogueInterpreter.open(SKILL_DIALOGUE, this)
}
/**
* Method used to display the content on the dialogue.
*/
fun display() {
if (type == null) {
player.debug("Error! Type is null.")
return
}
type.display(player, this)
}
/**
* Method used to create a product.
* @param amount the amount.
* @param index the index.
*/
open fun create(amount: Int, index: Int) {}
/**
* Gets the total amount of items to be made.
* @param index the index.
* @return the amount.
*/
open fun getAll(index: Int): Int {
return player.inventory.getAmount(data[0] as Item)
}
/**
* Gets the name.
* @param item the item.
* @return the name.
*/
protected open fun getName(item: Item): String {
return StringUtils.formatDisplayName(item.name.replace("Unfired", ""))
}
/**
* Represents a skill dialogue type.
* @author 'Vexia
*/
enum class SkillDialogue
/**
* Constructs a new `SkillDialogue` `Object`.
* @param interfaceId the interface id.
* @param base the base button.
* @param length the length.
*/(
/**
* Represents the interface id.
*/
val interfaceId: Int,
/**
* Represents the base button.
*/
private val baseButton: Int,
/**
* Represents the length.
*/
private val length: Int) {
ONE_OPTION(309, 5, 1) {
override fun display(player: Player, handler: SkillDialogueHandler) {
val item = handler.data[0] as Item
player.packetDispatch.sendString("<br><br><br><br>" + item.name, 309, 6)
player.packetDispatch.sendItemZoomOnInterface(item.id, 160, 309, 2)
PacketRepository.send(RepositionChild::class.java, ChildPositionContext(player, 309, 6, 60, 20))
PacketRepository.send(RepositionChild::class.java, ChildPositionContext(player, 309, 2, 210, 30))
}
override fun getAmount(handler: SkillDialogueHandler, buttonId: Int): Int {
return when(buttonId){
5 -> 1
4 -> 5
3 -> -1 //-1 is used to prompt an "enter an amount"
else -> handler.getAll(getIndex(handler, buttonId))
}
}
},
TWO_OPTION(303, 7, 2) {
override fun display(player: Player, handler: SkillDialogueHandler) {
var item: Item
player.interfaceManager.openChatbox(Components.same_306)
for (i in handler.data.indices) {
item = handler.data[i] as Item
player.packetDispatch.sendString("<br><br><br><br>" + handler.getName(item), 303, 7 + i)
player.packetDispatch.sendItemZoomOnInterface(item.id, 160, 303, 2 + i)
}
}
override fun getIndex(handler: SkillDialogueHandler?, buttonId: Int): Int {
when (buttonId) {
6, 5, 4, 3 -> return 0
10, 9, 8, 7 -> return 1
}
return 1
}
override fun getAmount(handler: SkillDialogueHandler, buttonId: Int): Int {
when (buttonId) {
6, 10 -> return 1
5, 9 -> return 5
4, 8 -> return 10
3, 7 -> return -1
}
return 1
}
},
THREE_OPTION(304, 8, 3) {
override fun display(player: Player, handler: SkillDialogueHandler) {
var item: Item? = null
for (i in 0..2) {
item = handler.data[i] as Item
player.packetDispatch.sendItemZoomOnInterface(item.id, 135, 304, 2 + i)
player.packetDispatch.sendString("<br><br><br><br>" + item!!.name, 304, 304 - 296 + i * 4)
}
}
override fun getIndex(handler: SkillDialogueHandler?, buttonId: Int): Int {
when (buttonId) {
7, 6, 5, 4 -> return 0
11, 10, 9, 8 -> return 1
15, 14, 13, 12 -> return 2
}
return 1
}
override fun getAmount(handler: SkillDialogueHandler, buttonId: Int): Int {
when (buttonId) {
7, 11, 15 -> return 1
6, 10, 14 -> return 5
5, 9, 13 -> return 10
4, 8, 12 -> return -1
}
return 1
}
},
FOUR_OPTION(305, 9, 4) {
override fun display(player: Player, handler: SkillDialogueHandler) {
var item: Item? = null
for (i in 0..3) {
item = handler.data[i] as Item
player.packetDispatch.sendItemZoomOnInterface(item!!.id, 135, 305, 2 + i)
player.packetDispatch.sendString("<br><br><br><br>" + item.name, 305, 305 - 296 + i * 4)
}
}
override fun getIndex(handler: SkillDialogueHandler?, buttonId: Int): Int {
when (buttonId) {
5, 8, 6, 7 -> return 0
9, 10, 11, 12 -> return 1
13, 14, 15, 16 -> return 2
17, 18, 19, 20 -> return 3
}
return 0
}
override fun getAmount(handler: SkillDialogueHandler, buttonId: Int): Int {
when (buttonId) {
8, 12, 16, 20 -> return 1
7, 11, 15, 19 -> return 5
6, 10, 14, 18 -> return 10
5, 9, 13, 17 -> return -1
}
return 1
}
},
FIVE_OPTION(306, 7, 5) {
/**
* Represents the position data.
*/
private val positions = arrayOf(intArrayOf(10, 30), intArrayOf(117, 10), intArrayOf(217, 20), intArrayOf(317, 15), intArrayOf(408, 15))
override fun display(player: Player, handler: SkillDialogueHandler) {
var item: Item
player.interfaceManager.openChatbox(Components.same_306)
for (i in handler.data.indices) {
item = handler.data[i] as Item
player.packetDispatch.sendString("<br><br><br><br>" + handler.getName(item), 306, 10 + 4 * i)
player.packetDispatch.sendItemZoomOnInterface(item.id, 160, 306, 2 + i)
PacketRepository.send(RepositionChild::class.java, ChildPositionContext(player, 306, 2 + i, positions[i][0], positions[i][1]))
}
}
override fun getIndex(handler: SkillDialogueHandler?, buttonId: Int): Int {
when (buttonId) {
9, 8, 7, 6 -> return 0
13, 12, 11, 10 -> return 1
17, 16, 15, 14 -> return 2
21, 20, 19, 18 -> return 3
25, 24, 23, 22 -> return 4
}
return 0
}
override fun getAmount(handler: SkillDialogueHandler, buttonId: Int): Int {
when (buttonId) {
9, 13, 17, 21, 25 -> return 1
8, 12, 16, 20, 24 -> return 5
7, 11, 15, 19, 23 -> return 10
6, 10, 14, 18, 22 -> return -1
}
return 1
}
};
/**
* Gets the interfaceId.
* @return The interfaceId.
*/
/**
* Method used to display the content for this type.
* @param player the player.
* @param handler the handler.
*/
open fun display(player: Player, handler: SkillDialogueHandler) {}
/**
* Gets the amount.
* @param handler the handler.
* @param buttonId the buttonId.
* @return the amount.
*/
open fun getAmount(handler: SkillDialogueHandler, buttonId: Int): Int {
for (k in 0..3) {
for (i in 0 until length) {
val `val` = baseButton - k + 4 * i
if (`val` == buttonId) {
return if (k == 13) 1 else if (k == 8) 5 else if (k == 7) 10 else 6
}
}
}
return -1
}
/**
* Gets the index selected.
* @param handler the handler.
* @param buttonId the buttonId.
* @return the index selected.
*/
open fun getIndex(handler: SkillDialogueHandler?, buttonId: Int): Int {
var index = 0
for (k in 0..3) {
for (i in 1 until length) {
val `val` = baseButton + k + 4 * i
if (`val` == buttonId) {
return index + 1
} else if (`val` <= buttonId) {
index++
}
}
index = 0
}
return index
}
companion object {
/**
* Gets the type for the length.
* @param length2 the length to compare.
* @return the type.
*/
fun forLength(length2: Int): SkillDialogue? {
for (dial in values()) {
if (dial.length == length2) {
return dial
}
}
return null
}
}
}
companion object {
/**
* Represents the skill dialogue id.
*/
const val SKILL_DIALOGUE = 3 shl 16
}
/**
* Constructs a new `SkillDialogueHandler` `Object`.
* @param player the player.
* @param type the type.
* @param data the data.
*/
init {
this.data = data as Array<Any>
}
}
@@ -1,158 +0,0 @@
package core.game.content.dialogue
import core.game.component.Component
import core.tools.Items
import core.game.node.entity.player.Player
import core.game.node.entity.player.link.diary.DiaryType
import core.game.node.item.Item
import core.plugin.Initializable
import core.tools.Components
/**
* Thormac
* Involved in Scorpion Catcher
* @author afaroutdude
*/
@Initializable
class ThormacDialogue(player: Player? = null) : DialoguePlugin(player) {
val scorpionCageEmpty = Item(Items.SCORPION_CAGE_456)
val scorpionCageFull = Item(Items.SCORPION_CAGE_463)
val scorpionCages: IntArray = intArrayOf(
Items.SCORPION_CAGE_456,
Items.SCORPION_CAGE_457,
Items.SCORPION_CAGE_458,
Items.SCORPION_CAGE_459,
Items.SCORPION_CAGE_460,
Items.SCORPION_CAGE_461,
Items.SCORPION_CAGE_462,
Items.SCORPION_CAGE_463
)
val COMPONENT = Component(Components.staff_enchanting_332)
override fun open(vararg args: Any?): Boolean {
val scorpionStage = try {
player?.questRepository?.getStage("Scorpion Catcher") ?: 100
} catch (e: Exception) {
100
}
when (scorpionStage) {
0 -> {
npc("Hello I am Thormac the Sorcerer, I don't suppose you could be of assistance to me?");stage = 0
}
10, 20, 30, 40, 50, 60, 70, 80, 90 -> {
npc("How goes your quest?");stage = 70
}
100 -> {
npc("Thank you for rescuing my scorpions.");stage = 100
}
}
return true
}
override fun handle(interfaceId: Int, buttonId: Int): Boolean {
when (stage) {
999 -> {end()}
// initial convo
0 -> {options("What do you need assistance with?", "I'm a little busy.");stage++}
1 -> when(buttonId){
1 -> {player ("What do you need assistance with?");stage=2}
2 -> {player ("I'm a little busy.");stage=50}
}
2 -> {npc ("I've lost my pet scorpions. They're lesser Kharid scorpions, a very rare breed. I left their cage door open, now I don't know where they've gone. There's three of them, and they're quick little beasties. They're all over 2009scape.")}
3 -> {options ("So how would I go about catching them then?", "What's in it for me?", "I'm not interested then.");stage++}
4 -> when(buttonId){
1 -> {player("So how would I go about catching them then?");stage++}
2 -> {player("What's in it for me?");stage=20}}
3 -> {player ("I'm not interested then.");stage=51}
5 -> {npc("Well I have a scorpion cage here which you can use to catch them in.");stage++}
6 -> {
sendDialogue("Thormac gives you a cage.")
player.inventory.add(scorpionCageEmpty)
stage++
}
7 -> {npc ("If you go up to the village of Seers, to the North of here, one of them will be able to tell you where the scorpions are now.");stage++}
8 -> {options ("What's in it for me?", "Ok, I will do it then.");stage++}
9 -> when(buttonId){
1 -> {player("What's in it for me?");stage=20}
2 -> {
player("Ok, I will do it then.")
// start quest here
stage = 999
}
}
20 -> {npc ("Well I suppose I can aid you with my skills as a staff sorcerer. Most battlestaffs around here are a bit puny. I can beef them up for you a bit. If you go up to the village of Seers, to the North of here, one of them will be able to tell you where the scorpions are now.");stage++}
21 -> {options("So how would I go about catching them then?","Ok, I will do it then.");stage++}
22 -> when(buttonId) {
1 -> {player("So how would I go about catching them then?");stage=5}
2 -> {
player("Ok, I wil do it then.")
// start quest here
stage = 999
}
}
50 -> {npc ("Come back if you have some spare time.");stage=999} // invention
51 -> {npc ("Come back if you change your mind.");stage=999} // invention
// after that
70 -> {
if (!player.inventory.containsAtLeastOneItem(scorpionCages)
&& !player.bank.containsAtLeastOneItem(scorpionCages)) {
player("I've lost my cage.")
stage = 71
} else if (!player.inventory.containsAtLeastOneItem(scorpionCageFull.id)) {
player("I've not caught all the scorpions yet.")
stage = 72
} else {
player("I have retrieved all your scorpions.")
stage = 73
}
}
71 -> {
// if lost or destroyed cage
npc("Ok, here's another cage. You're almost as bad at losing things as me.")
player.inventory.add(scorpionCageEmpty)
stage=999
}
72 -> {npc("Well remember to go speak to the Seers, North of here, if you need any help.");stage=999}
73 -> {
npc("Aha, my little scorpions home at last!")
// complete quest here
stage=999
}
// post-quest
100 -> {
if (!player.inventory.contains(84,1)) {
options("That's okay.", "You said you'd enchant my battlestaff for me.")
} else {
options("That's okay.", "You said you'd enchant my battlestaff for me.", "Could you enchant my Armadyl battlestaff?")
}
stage++
}
101 -> when (buttonId) {
1 -> {player("That's okay.");stage=999}
2 -> {player ("You said you'd enchant my battlestaff for me.");stage=110}
3 -> {player ("Could you enchant my Armadyl battlestaff?");stage=150}
}
110 -> {npc("Yes, although it'll cost you 40,000 coins for the","materials. What kind of staff did you want enchanting?");stage++}
111 -> {
end()
player.interfaceManager.open(COMPONENT)
player.achievementDiaryManager.finishTask(player, DiaryType.SEERS_VILLAGE, 1, 1)
}
}
return true;
}
override fun newInstance(player: Player?): DialoguePlugin {
return ThormacDialogue(player)
}
override fun getIds(): IntArray {
return intArrayOf(389)
}
}
@@ -1,248 +0,0 @@
package core.game.content.dialogue
import core.game.content.global.BirdNest
import core.game.node.entity.npc.NPC
import core.game.node.entity.player.Player
import core.game.node.entity.player.link.diary.DiaryLevel
import core.game.node.entity.player.link.diary.DiaryType
import core.game.node.item.GroundItemManager
import core.game.node.item.Item
import core.plugin.Initializable
import core.tools.Items
/**
* Represents the Wyson the gardener dialogue.
* @author 'Vexia
* @version 1.0
*/
@Initializable
class WysonTheGardenerDialogue : DialoguePlugin {
/**
* If its a bird nest reward.
*/
private var birdNest = false
/**
* Constructs a new `WysonTheGardenerDialogue` `Object`.
*/
constructor() {
/**
* empty.
*/
}
/**
* Constructs a new `WysonTheGardenerDialogue` `Object`.
* @param player the player.
*/
constructor(player: Player?) : super(player) {}
override fun newInstance(player: Player): DialoguePlugin {
return WysonTheGardenerDialogue(player)
}
override fun open(vararg args: Any): Boolean {
npc = args[0] as NPC
birdNest = player.inventory.containsItem(MOLE_CLAW) || player.inventory.containsItem(MOLE_SKIN)
if (birdNest) {
npc("If I'm not mistaken, you've got some mole bits there!", "I'll trade 'em for bird nest if ye likes.")
stage = 100
return true
}
npc("I'm the head gardener around here.", "If you're looking for woad leaves, or if you need help", "with owt, I'm yer man.")
stage = 0
return true
}
override fun handle(interfaceId: Int, buttonId: Int): Boolean {
when (stage) {
0 -> {
options("Yes please, I need woad leaves.", "Sorry, but I'm not interested.")
stage = 1
}
1 -> when (buttonId) {
1 -> {
player("Yes please, I need woad leaves.")
stage = 10
}
2 -> {
player("Sorry, but I'm not interested.")
stage = 200
}
}
10 -> {
npc("How much are you willing to pay?")
stage = 11
}
11 -> {
options("How about 5 coins?", "How about 10 coins?", "How about 15 coins?", "How about 20 coins?")
stage = 12
}
12 -> when (buttonId) {
1 -> {
player("How about 5 coins?")
stage = 110
}
2 -> {
player("How about 10 coins?")
stage = 110
}
3 -> {
player("How about 15 coins?")
stage = 130
}
4 -> {
player("How about 20 coins?")
stage = 140
}
}
110 -> {
npc("No no, that's far too little. Woad leaves are hard to get. I", "used to have plenty but someone kept stealing them off", "me.")
stage = 111
}
111 -> end()
130 -> {
npc("Mmmm... ok, that sounds fair.")
stage = 131
}
131 -> if (player.inventory.contains(995, 15)) {
player.inventory.remove(COINS[0])
player.inventory.add(WOAD_LEAF)
player("Thanks.")
player.packetDispatch.sendMessage("You buy a woad leaf from Wyson.")
stage = 132
} else {
end()
player.packetDispatch.sendMessage("You need 15 cold coins to buy a woad leaf.")
}
132 -> {
npc("I'll be around if you have any more gardening needs.")
stage = 133
}
133 -> end()
140 -> {
npc("Thanks for being generous", "here's an extra woad leave.")
stage = 141
}
141 -> if (player.inventory.contains(995, 20)) {
player.inventory.remove(COINS[1])
var i = 0
while (i < 2) {
player.inventory.add(WOAD_LEAF, player)
i++
}
player("Thanks.")
player.packetDispatch.sendMessage("You buy two woad leaves from Wyson.")
stage = 132
} else {
end()
player.packetDispatch.sendMessage("You need 15 cold coins to buy a woad leaf.")
}
200 -> {
npc("Fair enough.")
stage = 201
}
201 -> end()
100 -> {
options("Yes, I will trade the mole claws.", "Okay, I will trade the mole skin.", "I'd like to trade both.", "No, thanks.")
stage = 900
}
900 -> when (buttonId) {
1 -> {
player("Yes, I will trade the mole claws.")
stage = 910
}
2 -> {
player("Okay, I will trade the mole skin.")
stage = 920
}
3 -> {
player("I'd like to trade both.")
stage = 930
}
4 -> {
player("No, thanks.")
stage = 999
}
}
910 -> {
if (!player.inventory.containsItem(MOLE_CLAW)) {
player("Sorry, I don't have any mole claws.")
stage = 999
}
end()
addRewards()
}
920 -> {
if (!player.inventory.containsItem(MOLE_SKIN)) {
player("Sorry, I don't have any mole skins.")
stage = 999
}
end()
addRewards()
}
930 -> {
if (!player.inventory.containsItem(MOLE_CLAW) && !player.inventory.containsItem(MOLE_SKIN)) {
player("Sorry, I don't have any.")
stage = 999
}
addRewards()
end()
}
999 -> end()
}
return true
}
/**
* Adds nests.
* @param nestAmount the amount.
*/
private fun addRewards() {
val moleClaws = player.inventory.getAmount(Items.MOLE_CLAW_7416)
val moleSkin = player.inventory.getAmount(Items.MOLE_SKIN_7418)
val nestAmount = moleClaws + moleSkin
//Remove claws and skins
player.inventory.remove(Item(Items.MOLE_CLAW_7416,moleClaws))
player.inventory.remove(Item(Items.MOLE_SKIN_7418, moleSkin))
//Add white lily seeds if the player has the hard diary done
if(moleSkin > 0 && player.achievementDiaryManager.getDiary(DiaryType.FALADOR).checkComplete(DiaryLevel.HARD)) {
player.inventory.add(Item(14589, moleSkin), player)
}
//Add nests
for (i in 0 until nestAmount) {
if(!player.inventory.add(Item(BirdNest.getRandomNest(true).nest.id, 1), player)){
GroundItemManager.create(Item(BirdNest.getRandomNest(true).nest.id,1),player.location,player)
}
}
}
override fun getIds(): IntArray {
return intArrayOf(36)
}
companion object {
/**
* Represents the coins item that can be used.
*/
private val COINS = arrayOf(Item(995, 15), Item(995, 20))
/**
* Represents the woad leaf item.
*/
private val WOAD_LEAF = Item(1793, 1)
/**
* The mole claw item.
*/
private val MOLE_CLAW = Item(7416)
/**
* The mole skin.
*/
private val MOLE_SKIN = Item(7418)
}
}
@@ -1,17 +0,0 @@
package core.game.content.global
import core.game.content.dialogue.DialogueFile
import core.game.node.item.Item
import core.tools.START_DIALOGUE
class EnchantedJewelleryDialogueFile(val jewellery: EnchantedJewellery, val item: Item) : DialogueFile() {
override fun handle(componentID: Int, buttonID: Int) {
when(stage){
START_DIALOGUE -> interpreter!!.sendOptions("Where would you like to go?", *jewellery.options).also { stage++ }
1 -> {
jewellery.use(player, item, buttonID - 1, player!!.equipment.containsItem(item))
end()
}
}
}
}
@@ -1,121 +0,0 @@
package core.game.content.global.action
import core.game.world.GameWorld.ticks
import core.game.interaction.OptionHandler
import core.plugin.Plugin
import core.game.world.GameWorld
import core.game.world.map.zone.ZoneBorders
import core.game.node.entity.player.link.diary.DiaryType
import core.game.system.config.ItemConfigParser
import core.game.node.entity.combat.equipment.WeaponInterface
import core.game.content.global.action.EquipHandler
import core.game.node.entity.player.link.audio.Audio
import core.game.container.impl.EquipmentContainer
import core.game.interaction.OptionListener
import core.game.node.Node
import core.game.node.entity.player.Player
import core.game.node.item.Item
import core.tools.Items
/**
* Represents the equipment equipping handler plugin.
* @author Ceikry
* @author Woah
*/
class EquipHandler : OptionListener() {
override fun defineListeners() {
on("equip",ITEM){player,node ->
val item = node.asItem()
if(item == null || player.inventory[item.slot] != item){
return@on true
}
val equipStateListener = item.definition.getConfiguration<Plugin<Any>>("equipment", null)
if(equipStateListener != null){
val bool = equipStateListener.fireEvent("equip",player,item)
if(bool != true){
return@on true
}
}
val lock = player.locks.equipmentLock
if (lock != null && lock.isLocked) {
if (lock.message != null) {
player.packetDispatch.sendMessage(lock.message)
}
return@on true
}
player.setAttribute("equipLock:" + item.id, ticks + 2)
if (player.equipment.add(item, item.slot, true, true)) {
//check if a brawling glove is being equipped and register it
if (item.id in 13845..13857) {
player.debug("Registering gloves... ID: " + item.id)
player.brawlingGlovesManager.registerGlove(item.id)
}
if (item.id == Items.BLACK_CHAINBODY_1107 && player.getAttribute("diary:falador:black-chain-bought", false)
&& ZoneBorders(2969, 3310, 2975, 3314, 0).insideBorder(player)
) {
player.achievementDiaryManager.finishTask(player, DiaryType.FALADOR, 0, 2)
}
player.dialogueInterpreter.close()
player.audioManager.send(item.definition.getConfiguration(ItemConfigParser.EQUIP_AUDIO, 2244))
if (player.properties.autocastSpell != null) {
player.properties.autocastSpell = null
val wif = player.getExtension<WeaponInterface>(WeaponInterface::class.java)
wif.selectAutoSpell(-1, true)
wif.openAutocastSelect()
}
}
return@on true
}
}
companion object {
/**
* Unequips an item.
* @param player the player.
* @param slot the slot.
* @param itemId the item id.
*/
@JvmStatic
fun unequip(player: Player, slot: Int, itemId: Int) {
if (slot < 0 || slot > 13) {
return
}
val item = player.equipment[slot] ?: return
val lock = player.locks.equipmentLock
if (lock != null && lock.isLocked) {
if (lock.message != null) {
player.packetDispatch.sendMessage(lock.message)
}
return
}
if (slot == EquipmentContainer.SLOT_WEAPON) {
player.packetDispatch.sendString("", 92, 0)
}
val maximumAdd = player.inventory.getMaximumAdd(item)
if (maximumAdd < item.amount) {
player.packetDispatch.sendMessage("Not enough free space in your inventory.")
return
}
val plugin = item.definition.getConfiguration<Plugin<Any>>("equipment", null)
if (plugin != null) {
if (!(plugin.fireEvent("unequip", player, item) as Boolean)) {
return
}
}
if (player.equipment.remove(item)) {
player.audioManager.send(Audio(2238, 10, 1))
player.dialogueInterpreter.close()
player.inventory.add(item)
}
}
}
}
@@ -1,118 +0,0 @@
package core.game.content.global.action
import core.tools.Items
import core.game.content.global.GodType
import core.game.node.entity.player.Player
import core.game.node.entity.player.link.audio.Audio
import core.game.node.entity.player.link.diary.DiaryType
import core.game.node.item.GroundItem
import core.game.node.item.GroundItemManager
import core.game.node.item.Item
import core.game.system.config.GroundSpawnLoader.GroundSpawn
import core.game.world.GameWorld
import core.game.world.map.RegionManager
import core.game.world.update.flag.context.Animation
import plugin.ai.AIRepository.Companion.getItems
import core.game.content.dialogue.FacialExpression
import core.game.node.entity.skill.runecrafting.RunePouch
import core.game.system.SystemLogger
/**
* A class used to handle the picking up of ground items.
* @author 'Vexia
*/
object PickupHandler {
/**
* Method used to take a ground item.
* @param player the player.
* @param item the item.
* @return `True` if taken.
*/
@JvmStatic
fun take(player: Player, item: GroundItem): Boolean {
if (item.location == null) {
player.packetDispatch.sendMessage("Invalid ground item!")
return true
}
if (!GroundItemManager.getItems().contains(item)) {
player.packetDispatch.sendMessage("Too late!")
return true
}
if (player.getAttribute("droppedItem:" + item.id, 0) > GameWorld.ticks) { //Splinter
SystemLogger.logAlert("$player tried to do the drop & quick pick-up Ground Item dupe.")
return true
}
if (item !is GroundSpawn && item.isRemainPrivate && !item.droppedBy(player)) {
player.sendMessage("You can't take that item!")
return true
}
val add = Item(item.id, item.amount, item.charge)
if (!player.inventory.hasSpaceFor(add)) {
player.packetDispatch.sendMessage("You don't have enough inventory space to hold that item.")
return true
}
if (!canTake(player, item, 0)) {
return true
}
if (item.isActive && player.inventory.add(add)) {
if (!RegionManager.isTeleportPermitted(item.location)) {
player.animate(Animation.create(535))
}
if (item is GroundSpawn && item.getId() == Items.SEAWEED_401
&& player.zoneMonitor.isInZone("karamja")
&& !player.achievementDiaryManager.hasCompletedTask(DiaryType.KARAMJA, 0, 7)) {
var seaweed = player.getAttribute("seaweed", 0)
seaweed++
player.setAttribute("seaweed", seaweed)
player.achievementDiaryManager.updateTask(player, DiaryType.KARAMJA, 0, 7, seaweed >= 5)
}
// Collect five palm leaves
if (item.getId() == Items.PALM_LEAF_2339 && player.zoneMonitor.isInZone("karamja") && !player.achievementDiaryManager.hasCompletedTask(DiaryType.KARAMJA, 2, 7)) {
var palms = player.getAttribute("palms", 0)
palms++
player.setAttribute("palms", palms)
player.achievementDiaryManager.updateTask(player, DiaryType.KARAMJA, 2, 7, palms >= 5)
}
GroundItemManager.destroy(item)
if (item.dropper?.isArtificial == true) {
getItems(item.dropper)?.remove(item)
}
player.audioManager.send(Audio(2582, 10, 1))
}
return true
}
/**
* Checks if the player can take an item.
* @param player the player.
* @param item the item.
* @param type the type (1= ground, 2=telegrab)
* @return `True` if so.
*/
@JvmStatic
fun canTake(player: Player, item: GroundItem, type: Int): Boolean {
if (item.dropper != null && !item.droppedBy(player) && player.ironmanManager.checkRestriction()) {
return false
}
if (item.id == 8858 || item.id == 8859) {
player.dialogueInterpreter.sendDialogues(4300, FacialExpression.FURIOUS, "Hey! You can't take that, it's guild property. Take one", "from the pile.")
return false
}
if (GodType.forCape(item) != null) {
if (GodType.hasAny(player)) {
player.sendMessages("You may only possess one sacred cape at a time.", "The conflicting powers of the capes drive them apart.")
return false
}
}
if (RunePouch.forItem(item) != null) {
if (player.hasItem(item)) {
player.sendMessage("A mystical force prevents you from picking up the pouch.")
return false
}
}
return if (item.hasItemPlugin()) {
item.plugin.canPickUp(player, item, type)
} else true
}
}
@@ -1,180 +0,0 @@
package core.game.content.global.travel
import core.game.node.entity.impl.Projectile
import core.game.node.entity.npc.NPC
import core.game.node.entity.player.Player
import core.game.node.entity.player.link.diary.DiaryType
import core.game.node.item.Item
import core.game.system.task.Pulse
import core.game.world.GameWorld
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
/**
* Represents a utilitity class for rune essence teleporting.
* @author 'Vexia
*/
object EssenceTeleport {
/**
* Array of all the possible `Location` locations.
*/
val LOCATIONS = arrayOf(Location.create(2911, 4832, 0), Location.create(2913, 4837, 0), Location.create(2930, 4850, 0), Location.create(2894, 4811, 0), Location.create(2896, 4845, 0), Location.create(2922, 4820, 0), Location.create(2931, 4813, 0))
/**
* Represents the animation to use.
*/
private val ANIMATION = Animation(437)
/**
* Method used to teleport a player.
* @param npc the npc.
* @param player the player.
*/
@JvmStatic
fun teleport(npc: NPC, player: Player) {
npc.animate(ANIMATION)
npc.faceTemporary(player, 1)
npc.graphics(Graphics(108))
player.lock()
player.audioManager.send(195)
Projectile.create(npc, player, 109).send()
npc.sendChat("Senventior Disthinte Molesko!")
GameWorld.Pulser.submit(object : Pulse(1) {
var counter = 0
override fun pulse(): Boolean {
when (counter++) {
2 -> {
if (getStage(player) == 2 && player.inventory.contains(5519, 1)) {
val item = player.inventory[player.inventory.getSlot(Item(5519))]
if (item != null) {
if (item.charge == 1000) {
player.savedData.globalData.resetAbyss()
}
val wizard = Wizard.forNPC(npc.id)
if (!player.savedData.globalData.hasAbyssCharge(wizard.ordinal)) {
player.savedData.globalData.setAbyssCharge(wizard.ordinal)
item.charge = item.charge + 1
if (item.charge == 1003) {
player.sendMessage("Your scrying orb has absorbed enough teleport information.")
player.inventory.remove(Item(5519))
player.inventory.add(Item(5518))
}
}
}
}
player.savedData.globalData.essenceTeleporter = npc.id
val loc: Location =Location.create(2922, 4820, 0)
player.properties.teleportLocation = loc
if (npc.id == 553) {
player.achievementDiaryManager.finishTask(player, DiaryType.VARROCK, 0, 1)
}
if (npc.id == 300) {
player.achievementDiaryManager.finishTask(player, DiaryType.LUMBRIDGE, 1, 14)
}
}
3 -> {
player.graphics(Graphics(110))
player.unlock()
return true
}
}
return false
}
})
}
/**
* Method used to teleport back to the home.
* @param player the prayer.
*/
@JvmStatic
fun home(player: Player) {
val wizard = Wizard.forNPC(player.savedData.globalData.essenceTeleporter)
Projectile.create(player, player, 345).send()
player.properties.teleportLocation = wizard.location
}
/**
* Gets the stage.
* @return the stage.
*/
fun getStage(player: Player): Int {
return player.varpManager.get(492).getValue()
}
/**
* Method used to get a random location.
* @return the location.
*/
val location: Location
get() {
val count = RandomFunction.random(LOCATIONS.size)
return LOCATIONS[count]
}
/**
* Represents the wizard npc who can teleport.
* @author 'Vexia
*/
enum class Wizard
/**
* Constructs a new `WizardTowerPlugin` `Object`.
* @param npc the npc.
* @param location the location.
*/(
/**
* Represents the npc of this wizard.
*/
val npc: Int,
/**
* The mask.
*/
val mask: Int,
/**
* Represents the returining location.
*/
val location: Location) {
AUBURY(553, 0x2, Location(3253, 3401, 0)),
SEDRIDOR(300, 0x4, Location(3107, 9573, 0)),
DISTENTOR(462, 0x8, Location(2591, 3085, 0)),
CROMPERTY(2328, 0x12, Location.create(2682, 3323, 0));
/**
* Gets the npc.
* @return The npc.
*/
/**
* Gets the mask.
* @return The mask.
*/
/**
* Gets the location.
* @return The location.
*/
companion object {
/**
* Method used to get a wizard by the npc.
* @param npc the npc.
* @return the wizard.
*/
fun forNPC(npc: Int): Wizard {
for (wizard in values()) {
if (npc == 844) {
return CROMPERTY
}
if (wizard.npc == npc) {
return wizard
}
}
return AUBURY
}
}
}
}
@@ -1,80 +0,0 @@
package core.game.content.global.worldevents
import core.game.system.SystemLogger
import core.plugin.Plugin
import core.plugin.PluginManager
import java.util.*
/**
* The class other world events should extend off of.
* @author Ceikry
*/
open class WorldEvent(var name: String) {
var plugins = PluginSet()
/**
* if the event is active or not. Can be used to check dates or just always return true
* whatever you need for this specific event
*/
open fun checkActive(): Boolean {
return false
}
/**
* Check to see if the event should trigger. An event trigger could spawn shooting stars, or a world boss
* or whatever kind of whacky shit you need it to do.
*/
open fun checkTrigger(): Boolean{
return true
}
/**
* Used to initialize the event, which loads all associated plugins.
* The WorldEventInitializer runs this if checkActive() returns true.
*/
open fun initialize(){
plugins.initialize()
}
/**
* Used to log world event messages in a standard and organized way.
*/
fun log(message: String){
SystemLogger.logInfo("[World Events($name)] $message")
}
/**
* Used to start, or "fire", world events.
*/
open fun fireEvent() {}
}
/**
* A class that holds a set of plugins that shouldn't be initialized by default.
* Can be used to initialize all of its plugins cleanly.
*/
class PluginSet(vararg val plugins: Plugin<*>){
val set = ArrayList(plugins.asList())
fun initialize() {
PluginManager.definePlugins(*set.toTypedArray())
}
fun add(plugin: Plugin<*>){
set.add(plugin)
}
}
/**
* Static object for storing instances of loaded events.
*/
object WorldEvents {
private var events = hashMapOf<String,WorldEvent>()
fun add(event: WorldEvent){
events.put(event.name.toLowerCase(),event)
}
fun get(name: String): WorldEvent?{
return events.get(name.toLowerCase())
}
}
@@ -1,34 +0,0 @@
package core.game.content.global.worldevents
import core.plugin.Initializable
import core.plugin.Plugin
import io.github.classgraph.ClassGraph
import io.github.classgraph.ClassInfo
import java.util.function.Consumer
/**
* Responsible for initializing world events
* @author Ceikry
*/
@Initializable
class WorldEventInitializer : Plugin<Any>{
override fun newInstance(arg: Any?): Plugin<Any> {
/**
* Here I used ClassGraph to scan the core.game.content.global.worldevents package for subclasses of the WorldEvent class and
* then initialize them if their active setting evaluates to true. This makes it so we don't have to manually add them to
* a list. It also prevents unnecessary plugins from being loaded if an event isn't currently active.
*/
val result = ClassGraph().enableClassInfo().whitelistPackages("core.game.content.global.worldevents").scan()
result.getSubclasses("core.game.content.global.worldevents.WorldEvent").forEach(Consumer { p: ClassInfo ->
val c = p.loadClass().newInstance() as WorldEvent
if(c.checkActive()) c.initialize().also { WorldEvents.add(c) }
})
return this
}
override fun fireEvent(identifier: String?, vararg args: Any?): Any {
return Unit
}
}
@@ -1,28 +0,0 @@
package core.game.content.global.worldevents.holiday
import core.game.node.entity.player.Player
import core.game.node.item.GroundItemManager
import core.game.node.item.Item
import core.tools.RandomFunction
import core.plugin.CorePluginTypes.XPGainPlugin
import core.game.node.entity.skill.Skills
import core.tools.stringtools.colorize
class CandyRewardPlugin : XPGainPlugin(){
override fun run(player: Player, skill: Int, amount: Double) {
val awardCandy = RandomFunction.random(1,200) == 55
val candy = Item(14084)
if(awardCandy){
if(!player.inventory.add(candy)){
GroundItemManager.create(candy,player)
}
player.sendMessage(colorize("%OYou receive a candy while training ${Skills.SKILL_NAME[skill]}!"))
}
}
override fun fireEvent(identifier: String?, vararg args: Any?): Any {
return Unit
}
}
@@ -1,78 +0,0 @@
package core.game.content.global.worldevents.holiday
import core.game.node.entity.combat.ImpactHandler
import core.game.node.entity.player.Player
import core.game.node.item.Item
import core.game.content.dialogue.DialoguePlugin
import core.game.content.dialogue.FacialExpression
class GrimDialogue(player: Player? = null) : DialoguePlugin(player){
var firstSpeak = true
val candy = Item(14084)
override fun newInstance(player: Player?): DialoguePlugin {
return GrimDialogue(player)
}
override fun open(vararg args: Any?): Boolean {
firstSpeak = !player.getAttribute("hween:grim_spoken",false)
if(firstSpeak){
npc("YOU! Yes.... you! Come here!")
stage = 0
} else {
npc("Hello, again, adventurer...")
stage = 100
}
return true
}
override fun handle(interfaceId: Int, buttonId: Int): Boolean {
when(stage){
0 -> player(FacialExpression.AFRAID,"W-what... what do you want with","me?").also { stage++ }
1 -> npc("I want you.... I NEED you....").also { stage++ }
2 -> npc("TO BRING ME CANDY! Yes, candy...").also { stage++ }
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 }
100 -> npc("I do hope you have... candy for me?").also { stage++ }
101 -> if(player.inventory.containsItem(candy)){
player("Yes, I do! Here you go.").also { stage = 150 }
} 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 }
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 }
}
1000 -> end()
}
return true
}
override fun getIds(): IntArray {
return intArrayOf(6390)
}
}
@@ -1,30 +0,0 @@
package core.game.content.global.worldevents.holiday
import core.game.node.entity.npc.NPC
import core.game.world.GameWorld
import core.game.world.map.Location
import core.game.content.global.worldevents.PluginSet
import core.game.content.global.worldevents.WorldEvent
import java.util.*
class SimpleHalloweenEvent : WorldEvent("hween"){
override fun checkActive(): Boolean {
return Calendar.getInstance().get(Calendar.MONTH) == Calendar.OCTOBER
}
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!"
log("Initialized.")
}
}
@@ -1,83 +0,0 @@
package core.game.content.global.worldevents.penguinhns
import core.game.component.Component
import core.game.node.entity.player.Player
import core.game.node.item.Item
import core.game.system.task.Pulse
import core.game.world.GameWorld
import core.game.content.dialogue.DialoguePlugin
import core.tools.Components
class LarryHandler(player: Player? = null) : DialoguePlugin(player){
override fun open(vararg args: Any?): Boolean {
options("Can I have a spy notebook?","Can I have a hint?","I'd like to turn in my points.").also { stage = 0; return true }
}
override fun newInstance(player: Player?): DialoguePlugin {
return LarryHandler(player)
}
override fun handle(interfaceId: Int, buttonId: Int): Boolean {
class HintPulse : Pulse(){
override fun pulse(): Boolean {
val hint = PenguinManager.penguins.random().hint
player.sendMessage("Here, I know one is...")
player.sendMessage(hint)
return true
}
}
when(stage){
0 -> when(buttonId){
1 -> player("Can I have a spy notebook?").also { stage++ }
2 -> player("Can I have a hint?").also { stage = 10 }
3 -> player("I'd like to turn in my points.").also { stage = 20 }
}
//Spy notebook
1 -> npc("Sure!").also { player.inventory.add(Item(13732));stage = 1000 }
//Hint
10 -> npc("Yes, but I will have to write it down","for you so these penguins don't overhear.").also { GameWorld.submit(HintPulse()); stage = 1000 }
//Point turn-in
20 -> if(player.getAttribute("phns:points",0) > 0) npc("Sure thing, what would you like to be","rewarded with?").also { stage++ } else npc("Uh, you don't have any points","to turn in.").also{stage = 1000}
21 -> options("Coins","Experience").also { stage++ }
22 -> when(buttonId){
1 -> player.inventory.add(Item(995, 6500 * player.getAttribute("phns:points",0))).also { player("Thanks!"); player.removeAttribute("phns:points");stage = 1000 }
2 -> {
player.setAttribute("caller",this)
player.interfaceManager.open(Component(Components.stat_advancement_interface_134).setCloseEvent { player1: Player?, c: Component? ->
player.interfaceManager.openDefaultTabs()
player.removeAttribute("lamp")
player.unlock()
true
}).also { end() }
}
}
1000 -> end()
}
return true
}
override fun handleSelectionCallback(skill: Int, player: Player?) {
val points = player?.getAttribute("phns:points",0)
if(points == 0){
player.sendMessage("Sorry, but you have no points to redeem.")
return
}
val level = player?.skills?.getLevel(skill) ?: 0
System.out.println("Level: $level")
val expGained = points?.toDouble()?.times((level * 25))
System.out.print("exp: $expGained")
player?.skills?.addExperience(skill,expGained!!)
player?.setAttribute("/save:phns:points",0)
}
override fun getIds(): IntArray {
return intArrayOf(5424)
}
}
@@ -1,22 +0,0 @@
package core.game.content.global.worldevents.penguinhns
import core.cache.def.impl.ItemDefinition
import core.game.interaction.OptionHandler
import core.game.node.Node
import core.game.node.entity.player.Player
import core.plugin.Plugin
class NotebookHandler : OptionHandler(){
override fun handle(player: Player?, node: Node?, option: String?): Boolean {
val total = player?.getAttribute("phns:points",0)
val weekly = player?.getAttribute("phns:weekly",0)
player?.dialogueInterpreter?.sendDialogue("Total points: $total","Penguins spied this week: $weekly")
return true
}
override fun newInstance(arg: Any?): Plugin<Any> {
ItemDefinition.forId(13732).handlers["option:read"] = this
return this
}
}
@@ -1,50 +0,0 @@
package core.game.content.global.worldevents.penguinhns
import core.game.system.task.Pulse
import core.game.world.GameWorld
import core.game.content.global.worldevents.PluginSet
import core.game.content.global.worldevents.WorldEvent
import core.game.content.global.worldevents.WorldEvents
class PenguinHNSEvent : WorldEvent("penguin-hns"){
val manager = PenguinManager()
var lastTrigger: Int = 0
var tickDelay = if(GameWorld.settings?.isDevMode == true) 100 else 100000
override fun checkActive(): Boolean {
return true //this event is always active.
}
override fun checkTrigger(): Boolean {
return GameWorld.ticks - lastTrigger >= tickDelay
}
override fun initialize() {
plugins = PluginSet(
LarryHandler(),
NotebookHandler(),
PenguinSpyingHandler()
)
super.initialize()
GameWorld.Pulser.submit(PenguinRegeneration())
log("Penguin HNS initialized.")
}
override fun fireEvent() {
log("Reshuffling Penguins...")
manager.rebuildVars()
lastTrigger = GameWorld.ticks
log("Penguins Reshuffled.")
}
class PenguinRegeneration : Pulse(25){
override fun pulse(): Boolean {
val event = WorldEvents.get("penguin-hns")
event ?: return true
if(event.checkTrigger()) event.fireEvent()
return false
}
}
}
@@ -1,32 +0,0 @@
package core.game.content.global.worldevents.penguinhns
import core.game.node.entity.npc.NPC
import core.game.system.SystemLogger
import core.game.world.map.Location
import java.util.*
class PenguinManager{
companion object {
var penguins = ArrayList<PenguinSpawner.Penguin>()
var npcs = ArrayList<NPC>()
val spawner = PenguinSpawner()
var tagMapping = HashMap<Location,ArrayList<String>>()
}
fun rebuildVars() {
for(p in npcs){
p.clear()
p.isActive = false
}
npcs.clear()
penguins = spawner.spawnPenguins(6)
tagMapping.clear()
for(p in penguins){
tagMapping.put(p.loc, ArrayList())
}
}
fun log(message: String){
SystemLogger.logInfo("[Penguins] $message")
}
}
@@ -1,56 +0,0 @@
package core.game.content.global.worldevents.penguinhns
import core.game.node.entity.npc.NPC
import core.game.world.map.Location
import core.game.content.global.worldevents.WorldEvents
import kotlin.collections.ArrayList
class PenguinSpawner {
val CACTUS = 8107
val CRATE = 8108
val BARREL = 8104
val BUSH = 8105
val ROCK = 8109
val TOADSTOOL = 8110
class Penguin(val id: Int, val hint: String, val loc: Location)
val penguins = arrayListOf<Penguin>(
Penguin(CACTUS,"...located in the northern desert.",Location.create(3310, 3157, 0)),
Penguin(BUSH,"...located between Fremennik and barbarians.",Location.create(2532, 3588, 0)),
Penguin(BUSH,"...located where banana smugglers dwell.",Location.create(2740, 3233, 0)),
Penguin(BUSH,"...located south of Ardougne.",Location.create(2456, 3092, 0)),
Penguin(BUSH,"...located deep in the jungle.",Location.create(2832, 3053, 0)),
Penguin(ROCK,"...located where the Imperial Guard train.",Location.create(2852, 3578, 0)),
Penguin(ROCK,"...located in the kingdom of Misthalin.",Location.create(3356, 3416, 0)),
Penguin(CRATE,"...located in the kingdom of Misthalin.",Location.create(3112, 3332, 0)),
Penguin(BUSH,"...located where eagles fly.",Location.create(2326, 3516, 0)),
Penguin(BARREL,"...located where no weapons may go.",Location.create(2806, 3383, 0)),
Penguin(ROCK,"...located near some ogres.",Location.create(2631, 2980, 0)),
Penguin(BUSH,"...located south of Ardougne.",Location.create(2513, 3154, 0)),
Penguin(BUSH,"...located near a big tree surrounded by short people.",Location.create(2387, 3451, 0)),
Penguin(BUSH,"...located in the kingdom of Asgarnia.",Location.create(2951, 3511, 0)),
Penguin(ROCK,"...located in the Kingdom of Asgarnia.",Location.create(3013, 3501, 0)),
Penguin(ROCK,"...located between Fremennik and barbarians.",Location.create(2532, 3630, 0)),
Penguin(CRATE,"...located in the Kingdom of Misthalin.",Location.create(3305, 3508, 0)),
Penguin(TOADSTOOL,"...located in the kingdom of Misthalin.",Location.create(3156, 3178, 0)),
Penguin(BUSH,"...located in the northern desert.",Location.create(3350, 3311, 0)),
Penguin(BUSH,"...located somewhere in the kingdom of Kandarin.",Location.create(2633, 3501, 0)),
Penguin(BUSH,"...located south of Ardougne.",Location.create(2440, 3206, 0)),
Penguin(CACTUS,"...located in the southern desert.",Location.create(3259, 3052, 0)),
Penguin(BUSH,"...located where wizards study.",Location.create(3112, 3149, 0)),
Penguin(TOADSTOOL,"...located in the fairy realm.",Location.create(2409, 4462, 0))
)
fun spawnPenguins(amount: Int): ArrayList<Penguin> {
var event = WorldEvents.get("penguin-hns") as PenguinHNSEvent
var counter = 0
val list = penguins.toMutableList()
val penguinList = ArrayList<Penguin>()
while(counter < amount){
val peng = list.random()
penguinList.add(peng).also { NPC(peng.id,peng.loc).also {PenguinManager.npcs.add(it);it.isNeverWalks = true; it.isWalks = false}.init() }
list.remove(peng)
counter++
}
return penguinList
}
}
@@ -1,72 +0,0 @@
package core.game.content.global.worldevents.penguinhns
import core.game.interaction.DestinationFlag
import core.game.interaction.MovementPulse
import core.game.interaction.Option
import core.game.node.entity.npc.NPC
import core.game.node.entity.player.Player
import core.game.system.task.Pulse
import core.game.world.GameWorld
import core.game.world.update.flag.context.Animation
import core.plugin.Plugin
import core.game.content.quest.PluginInteraction
import core.game.content.quest.PluginInteractionManager
class PenguinSpyingHandler : PluginInteraction(8107,8108,8104,8105,8109,8110){
class SpyPulse(val player: Player) : Pulse() {
var stage = 0
val curPoints = player.getAttribute("phns:points",0)
val weeklyPoints = player.getAttribute("phns:weekly",0)
val WEEKLY_CAP = 10
val ANIMATION = Animation(10355)
override fun pulse(): Boolean {
when(stage++){
0 -> player.lock().also { player.animator.animate(ANIMATION) }
1 -> player.sendMessage("You manage to spy on the penguin.").also { player.setAttribute("/save:phns:points",curPoints + 1);player.setAttribute("/save:phns:weekly",weeklyPoints + 1);player.unlock();}
2 -> if(weeklyPoints + 1 >= WEEKLY_CAP) player.setAttribute("/save:phns:date", ((System.currentTimeMillis() * 0.001) + 604800).toLong())
3 -> return true
}
return false
}
}
override fun handle(player: Player?, npc: NPC?, option: Option?): Boolean {
class movePulse : MovementPulse(player,DestinationFlag.ENTITY.getDestination(player,npc)){
override fun pulse(): Boolean {
player.let { player?.face(npc);GameWorld.submit(SpyPulse(player!!)) }
return true
}
}
if(option?.name?.toLowerCase()?.equals("spy-on")!!){
val currentDate = System.currentTimeMillis() * 0.001
val playerDate: Long = player?.getAttribute("phns:date",0L)!!
if(currentDate < playerDate){
player.sendMessage("You have already earned your maximum number of points this week.").also { return true }
} else if(playerDate != 0L){
player.removeAttribute("phns:date")
player.removeAttribute("phns:weekly")
}
if(PenguinManager.tagMapping[npc?.location]?.contains(player.username)!!){
player.sendMessage("You've already tagged this penguin.")
} else {
GameWorld.submit(movePulse())
PenguinManager.tagMapping[npc?.location]?.add(player.username)
}
return true
}
return false
}
override fun fireEvent(identifier: String?, vararg args: Any?): Any {
return Unit
}
override fun newInstance(arg: Any?): Plugin<Any> {
PluginInteractionManager.register(this,PluginInteractionManager.InteractionType.NPC)
return this
}
}
@@ -1,152 +0,0 @@
package core.game.content.global.worldevents.shootingstar
import core.game.node.`object`.GameObject
import core.game.node.`object`.ObjectBuilder
import core.game.node.entity.npc.NPC
import core.game.node.entity.player.Player
import core.game.world.map.Location
import core.game.world.repository.Repository
/**
* Represents a shooting star object (Only ever initialized once) (ideally)
* @author Ceikry
*/
class ShootingStar(var level: ShootingStarType = ShootingStarType.values().random()){
val crash_locations = hashMapOf(
"Canifis Bank" to Location.create(3504, 3487, 0),
"Crafting Guild" to Location.create(2940, 3280, 0),
"Falador East Bank" to Location.create(3030, 3349, 0),
"Rimmington mining site" to Location.create(2975, 3237, 0),
"Rimmington mine" to Location.create(2975, 3240, 0),
"Karamja mining site" to Location.create(2737, 3223, 0),
"Brimhaven mining site" to Location.create(2743, 3143, 0),
"South Crandor mining site" to Location.create(2822, 3239, 0),
"Karamja mining site" to Location.create(2854, 3032, 0),
"Shilo Village mining site" to Location.create(2826, 2997, 0),
"Relleka mining site" to Location.create(2682, 3700, 0),
"Ardougne mining site" to Location.create(2600, 3232, 0),
"Yanille Bank" to Location.create(2603, 3087, 0),
"Al Kharid bank" to Location.create(3276, 3176, 0),
"Al Kharid mining site" to Location.create(3296, 3297, 0),
"Duel Arena bank chest" to Location.create(3342, 3267, 0),
"Nardah mining site" to Location.create(3320, 2872, 0),
"Nardah bank" to Location.create(3434, 2888, 0),
"South-east Varrock mine" to Location.create(3292, 3353, 0),
"South-west Varrock mine" to Location.create(3176, 3362, 0),
"Varrock east bank" to Location.create(3259, 3407, 0),
"Lumbridge Swamp mine" to Location.create(3227, 3150, 0),
"Gnome stronghold Bank" to Location.create(2460, 3432, 0),
"North Edgeville mining site" to Location.create(3101, 3569, 0),
"Southern wilderness mine" to Location.create(3025, 3591, 0),
"Pirates' Hideout mine" to Location.create(3059, 3940, 0),
"Lava Maze mining site" to Location.create(3062, 3885, 0),
"Mage Arena bank" to Location.create(3093, 3962, 0)
)
val starSprite = NPC(8091)
var location = "Canifis Bank"
var maxDust = level.totalStardust
var dustLeft = level.totalStardust
var starObject = GameObject(level.objectId, crash_locations.get(location))
var isDiscovered = false
var ticks = 0
var isSpawned = false
var spriteSpawned = false
/**
* Degrades a ShootingStar (or removes the starObject and spawns a Star Sprite if it's the last star)
*/
fun degrade() {
if(level.ordinal == 0){
ObjectBuilder.remove(starObject)
isSpawned = false
starSprite.location = starObject.location
starSprite.init()
spriteSpawned = true
return
}
level = getNextType()
maxDust = level.totalStardust
dustLeft = level.totalStardust
val newStar = GameObject(level.objectId, starObject.location)
ObjectBuilder.replace(starObject, newStar)
starObject = newStar
}
private fun getNextType(): ShootingStarType{
return ShootingStarType.values()[level.ordinal - 1]
}
/**
* Fires the shooting star (spawns a new one). Only used when spawning new shooting stars, not for downgrading existing ones.
*/
fun fire() {
ObjectBuilder.remove(starObject)
rebuildVars()
clearSprite()
ObjectBuilder.add(starObject)
isSpawned = true
Repository.sendNews("A shooting star level ${level.ordinal + 1} just crashed near ${location.toLowerCase()}!")
}
/**
* Rebuilds some of the variables with new information.
*/
fun rebuildVars(){
level = ShootingStarType.values().random()
location = crash_locations.entries.random().key
maxDust = level.totalStardust
dustLeft = level.totalStardust
starObject = GameObject(level.objectId, crash_locations.get(location))
isDiscovered = false
ticks = 0
}
fun clearSprite() {
starSprite.clear()
spriteSpawned = false
}
/**
* Decrement the amount of dust left in the current star and degrade it if the amount left is 0 or less.
*/
fun decDust() {
if(--dustLeft <= 0) degrade()
}
/**
* Proxy method for starting to mine a shooting star
*/
fun mine(player: Player) {
player.pulseManager.run(ShootingStarMiningPulse(player, starObject, this))
}
/**
* Prospecting shooting stars.
*/
fun prospect(player: Player) {
player.dialogueInterpreter.sendDialogue("This is a size " + (level.ordinal + 1) + " star. A Mining level of at least " + miningLevel + " is", "required to mine this layer. There is $dustLeft stardust remaining", "until the next layer.")
}
/**
* Gets the mining level required based on the star's current level ordinal.
*/
val miningLevel: Int
get() = (level.ordinal + 1) * 10
}
/**
* Various levels of shooting stars
* @author Ceikry
*/
enum class ShootingStarType(val objectId: Int, val exp: Int, val totalStardust: Int,val rate: Double) {
LEVEL_1(38668, 14, 1200, 0.05),
LEVEL_2(38667, 25, 700, 0.1),
LEVEL_3(38666, 29, 439, 0.3),
LEVEL_4(38665, 32, 250, 0.4),
LEVEL_5(38664, 47, 175, 0.5),
LEVEL_6(38663, 71, 80, 0.70),
LEVEL_7(38662, 114, 40, 0.80),
LEVEL_8(38661, 145, 25, 0.85),
LEVEL_9(38660, 210, 15, 0.95);
}
@@ -1,40 +0,0 @@
package core.game.content.global.worldevents.shootingstar
import core.game.node.entity.player.Player
import core.game.system.command.CommandPlugin
import core.game.system.command.CommandSet
import core.plugin.Plugin
import core.game.content.global.worldevents.WorldEvents
import java.util.concurrent.TimeUnit
/**
* A few assorted commands for shooting stars.
*/
class ShootingStarCommands : CommandPlugin(){
override fun newInstance(arg: Any?): Plugin<Any?>{
link(CommandSet.DEVELOPER)
return this
}
override fun parse(player: Player?, name: String?, args: Array<String?>?): Boolean {
val star = (WorldEvents.get("shooting-stars") as ShootingStarEvent).star
when (name) {
"tostar" -> {
player!!.teleport(star.starObject.location.transform(1, 1, 0))
}
"submit" -> {
star.fire()
}
"resettime" -> player!!.savedData.globalData.starSpriteDelay = 0L
"stardust" -> {
val dust = 8
println("Cosmic Runes: " + 0.76 * dust)
println("Astral runes: " + 0.26 * dust)
println("Gold ores: " + 0.1 * dust)
println("GP: " + 250.1 * dust)
}
"setsprite" -> player!!.savedData.globalData.starSpriteDelay = System.currentTimeMillis() + TimeUnit.DAYS.toMillis(1)
}
return true
}
}
@@ -1,81 +0,0 @@
package core.game.content.global.worldevents.shootingstar
import core.game.system.task.Pulse
import core.game.world.GameWorld
import core.game.content.global.worldevents.PluginSet
import core.game.content.global.worldevents.WorldEvent
import core.game.content.global.worldevents.WorldEvents
/**
* The world event class for shooting stars. Keeps track of event-related data like the ShootingStar instance.
* Also handles spawning new shooting stars based on time.
* @author Ceikry
*/
class ShootingStarEvent : WorldEvent("shooting-stars") {
val star = ShootingStar()
val tickDelay = if(GameWorld.settings?.isDevMode == true) 200 else 25000
override fun initialize() {
plugins = PluginSet(
ScoreboardHandler(),
ShootingStarOptionHandler(),
ShootingStarScoreboard(),
StarChartPlugin(),
ShootingStarCommands(),
StarSpriteDialogue(),
ShootingStarLogin()
)
super.initialize()
GameWorld.Pulser.submit(StarPulse())
log("Shooting Star event has been initialized.")
}
override fun checkTrigger(): Boolean {
/**
* Spawn a new star only if: star's ticks are greater than the tickDelay and star sprite is not spawned OR,
* neither the star or the sprite are spawned.
*/
star.ticks += 10
if ((star.ticks >= tickDelay && !star.spriteSpawned) || (!star.isSpawned && !star.spriteSpawned)) {
return true
}
/**
* Clear the sprite when we have passed the tickDelay + (1/3) of the tickDelay.
* This gives players a little extra time before the star respawns to run to the bank and grab
* stardust or whatever. Once the sprite is cleared a new star will be allowed to spawn.
*/
val maxDelay = tickDelay + (tickDelay / 3)
if(star.ticks > maxDelay && star.spriteSpawned){
star.clearSprite()
}
return false
}
override fun checkActive(): Boolean {
return true //this event is always active.
}
override fun fireEvent() {
log("Fired new shooting star event.")
star.fire()
}
/**
* Handles checking star status and spawning new ones if necessary.
*/
class StarPulse : Pulse(10){
override fun pulse(): Boolean {
val event = WorldEvents.get("shooting-stars")
event ?: return true
if(event.checkTrigger()){
event.fireEvent()
}
return false //always returns false because it needs to run forever.
}
}
}
@@ -1,29 +0,0 @@
package core.game.content.global.worldevents.shootingstar
import core.game.node.entity.player.Player
import core.plugin.Plugin
import core.plugin.PluginManifest
import core.plugin.PluginType
import core.game.content.global.worldevents.WorldEvents
/**
* A plugin that handles the message a player receives on login pertaining to shooting stars.
*/
@PluginManifest(type = PluginType.LOGIN)
class ShootingStarLogin : Plugin<Player?> {
@Throws(Throwable::class)
override fun newInstance(arg: Player?): Plugin<Player?>? {
if (arg is Player) {
val star = (WorldEvents.get("shooting-stars") as ShootingStarEvent).star
if (star.isSpawned) {
arg.sendMessage("<img=12><col=CC6600>News: A shooting star (Level " + (star.level.ordinal + 1).toString() + ") has just crashed near the " + star.location + "!")
}
return this
}
return this
}
override fun fireEvent(identifier: String, vararg args: Any): Any {
return Unit
}
}

Some files were not shown because too many files have changed in this diff Show More