ContentAPI improvements, ported some more content to using ContentAPI

This commit is contained in:
Ceikry
2021-06-22 10:27:28 -05:00
parent 7b47cf267f
commit 9986fb5b61
7 changed files with 188 additions and 60 deletions
+7
View File
@@ -0,0 +1,7 @@
package api
enum class Container {
INVENTORY,
BANK,
EQUIPMENT
}
+142 -11
View File
@@ -11,9 +11,9 @@ import core.game.node.entity.impl.Animator
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.TeleportManager
import core.game.node.entity.player.link.audio.Audio
import core.game.node.entity.player.link.emote.Emotes
import core.game.node.entity.skill.Skills
import core.game.node.entity.skill.gather.SkillingTool
import core.game.node.item.GroundItem
import core.game.node.item.GroundItemManager
@@ -23,7 +23,7 @@ import core.game.world.map.Location
import core.game.world.map.RegionManager
import core.game.world.map.path.Pathfinder
import core.game.world.update.flag.context.Animation
import rs09.ServerConstants
import core.game.world.update.flag.context.Graphics
import rs09.game.content.dialogue.DialogueFile
import rs09.game.system.SystemLogger
import rs09.game.world.GameWorld
@@ -115,14 +115,21 @@ object ContentAPI {
* Remove an item from a player's inventory
* @param player the player whose inventory to remove the item from
* @param item the ID or Item object to remove from the player's inventory
* @param container the Container to remove the items from. An enum exists for this in the api package called Container. Ex: api.Container.BANK
*/
@JvmStatic
fun <T> removeItem(player: Player, item: T): Boolean {
fun <T> removeItem(player: Player, item: T, container: Container): Boolean {
item ?: return false
when (item) {
is Item -> return player.inventory.remove(item)
is Int -> return player.inventory.remove(Item(item))
else -> SystemLogger.logErr("Attempted to pass a non-item and non-int to removeItem")
val it = when (item) {
is Item -> item
is Int -> Item(item)
else -> throw IllegalStateException("Invalid value passed for item")
}
when(container){
Container.INVENTORY -> player.inventory.remove(it)
Container.BANK -> player.bank.remove(it)
Container.EQUIPMENT -> player.equipment.remove(it)
}
return false
}
@@ -426,15 +433,21 @@ object ContentAPI {
/**
* Plays an animation on the entity
* @param entity the entity to animate
* @param anim the animation to play
* @param anim the animation to play, can be an ID or an Animation object.
* @param forced whether or not to force the animation (usually not necessary)
*/
@JvmStatic
fun animate(entity: Entity, anim: Animation, forced: Boolean = false) {
fun <T> animate(entity: Entity, anim: T, forced: Boolean = false) {
val animation = when(anim){
is Int -> Animation(anim)
is Animation -> anim
else -> throw IllegalStateException("Invalid value passed for anim")
}
if (forced) {
entity.animator.forceAnimation(anim)
entity.animator.forceAnimation(animation)
} else {
entity.animator.animate(anim)
entity.animator.animate(animation)
}
}
@@ -702,4 +715,122 @@ object ContentAPI {
else -> SystemLogger.logErr("Attempt to set the charge of invalid type: ${node.javaClass.simpleName}")
}
}
/**
* Gets the used option in the context of an interaction.
* @param player the player to get the used option for.
* @return the option the player used
*/
@JvmStatic
fun getUsedOption(player: Player): String {
return player.getAttribute("interact:option","INVALID")
}
/**
* Used to play both an Animation and Graphics object simultaneously.
* @param entity the entity to perform this on
* @param anim the Animation object to use, can also be an ID.
* @param gfx the Graphics object to use, can also be an ID.
*/
@JvmStatic
fun <A,G> visualize(entity: Entity, anim: A, gfx: G){
val animation = when(anim){
is Int -> Animation(anim)
is Animation -> anim
else -> throw IllegalStateException("Invalid parameter passed for animation.")
}
val graphics = when(gfx){
is Int -> Graphics(gfx)
is Graphics -> gfx
else -> throw IllegalStateException("Invalid parameter passed for graphics.")
}
entity.visualize(animation,graphics)
}
/**
* Used to submit a pulse to the GameWorld's Pulser.
* @param pulse the Pulse object to submit
*/
@JvmStatic
fun submitWorldPulse(pulse: Pulse){
GameWorld.Pulser.submit(pulse)
}
/**
* Teleports or "instantly moves" an entity to a given Location object.
* @param entity the entity to move
* @param loc the Location object to move them to
* @param type the teleport type to use (defaults to instant). An enum exists as TeleportManager.TeleportType.
*/
@JvmStatic
fun teleport(entity: Entity, loc: Location, type: TeleportManager.TeleportType = TeleportManager.TeleportType.INSTANT){
entity.teleporter.send(loc,type)
}
/**
* Sets the dynamic or "temporary" (restores) level of a skill.
* @param entity the entity to set the level for
* @param skill the Skill to set. A Skills enum exists that can be used. Ex: Skills.STRENGTH
* @param level the level to set the skill to
*/
@JvmStatic
fun setTempLevel(entity: Entity, skill: Int, level: Int){
entity.skills.setLevel(skill, level)
}
/**
* Gets the static (unchanging/max) level of an entity's skill
* @param entity the entity to get the level for
* @param skill the Skill to get the level of. A Skills enum exists that can be used. Ex: Skills.STRENGTH
* @return the static level of the skill
*/
@JvmStatic
fun getStatLevel(entity: Entity, skill: Int): Int {
return entity.skills.getStaticLevel(skill)
}
/**
* Gets the dynamic (boostable/debuffable/restoring) level of an entity's skill
* @param entity the entity to get the level for
* @param skill the Skill to get the level of. A Skills enum exists that can be used. Ex: Skills.STRENGTH
* @return the dynamic level of the skill
*/
@JvmStatic
fun getDynLevel(entity: Entity, skill: Int): Int {
return entity.skills.getLevel(skill)
}
/**
* Adjusts (buffs/debuffs) the given Skill by the amount given.
* @param entity the entity to adjust the skill for
* @param skill the Skill to adjust. A Skills enum exists that can be used. Ex: Skills.STRENGTH
* @param amount the amount to adjust the skill by. Ex-Buff: 5, Ex-Debuff: -5
*/
@JvmStatic
fun adjustLevel(entity: Entity, skill: Int, amount: Int){
entity.skills.setLevel(skill, entity.skills.getStaticLevel(skill) + amount)
}
/**
* Remove all of a given item from the given container
* @param player the player to remove the item from
* @param item the item to remove. Can be an Item object or an ID.
* @param container the Container to remove the item from. An enum exists for this called Container. Ex: Container.BANK
*/
@JvmStatic
fun <T> removeAll(player: Player, item: T, container: Container){
val it = when(item){
is Item -> item.id
is Int -> item
else -> throw IllegalStateException("Invalid value passed as item")
}
when(container){
Container.EQUIPMENT -> player.equipment.remove(Item(it, amountInEquipment(player, it)))
Container.BANK -> player.bank.remove(Item(it, amountInBank(player, it)))
Container.INVENTORY -> player.inventory.remove(Item(it, amountInInventory(player, it)))
}
}
}
@@ -176,6 +176,8 @@ object InteractionListeners {
val method = get(id,type,option) ?: get(option,type) ?: return false
val destOverride = getOverride(type, id, option) ?: getOverride(type,node.id) ?: getOverride(type,option.toLowerCase())
player.setAttribute("interact:option", option)
if(type != 0) {
if(player.locks.isMovementLocked) return false
player.pulseManager.run(object : MovementPulse(player, node, flag, destOverride) {
@@ -1,5 +1,6 @@
package rs09.game.interaction.item
import api.ContentAPI
import rs09.game.interaction.InteractionListener
/**
@@ -13,8 +14,8 @@ class BraceletOfClayPlugin : InteractionListener() {
override fun defineListeners() {
on(BRACELET,ITEM,"operate"){player,node ->
var charge = node.asItem().charge
if (charge > 28) charge = 28
var charge = ContentAPI.getCharge(node)
if (charge > 28) ContentAPI.setCharge(node, 28).also { charge = 28 }
player.sendMessage("You have $charge uses left.")
return@on true
}
@@ -1,5 +1,6 @@
package rs09.game.interaction.item
import api.ContentAPI
import core.game.node.Node
import core.game.node.entity.player.Player
import core.game.node.item.GroundItemManager
@@ -42,15 +43,13 @@ class CulChestItems: InteractionListener() {
}
fun alchemize(player: Player, node: Node){
val amount = player.inventory.getAmount(node.id) + player.equipment.getAmount(node.id)
val coins = amount * node.asItem().definition.value
val amount = ContentAPI.amountInInventory(player, node.id) + ContentAPI.amountInEquipment(player, node.id)
val coins = amount * ContentAPI.itemDefinition(node.id).value
player.inventory.remove(Item(node.id,player.inventory.getAmount(node.id)))
player.equipment.remove(Item(node.id))
if(!player.inventory.add(Item(995,coins))){
GroundItemManager.create(Item(995,coins),player)
}
ContentAPI.removeAll(player, node.id, api.Container.INVENTORY)
ContentAPI.removeItem(player, node.id, api.Container.EQUIPMENT)
ContentAPI.addItemOrDrop(player, 995, coins)
player.dialogueInterpreter.sendDialogue("The item instantly alchemized itself!")
ContentAPI.sendDialogue(player, "The item instantly alchemized itself!")
}
}
@@ -1,5 +1,6 @@
package rs09.game.interaction.item
import api.ContentAPI
import core.cache.def.impl.ItemDefinition
import core.game.content.global.travel.glider.GliderPulse
import core.game.content.global.travel.glider.Gliders
@@ -15,6 +16,7 @@ import core.game.world.update.flag.context.Graphics
import core.plugin.Initializable
import core.plugin.Plugin
import org.rs09.consts.Items
import rs09.game.interaction.InteractionListener
import rs09.game.world.GameWorld
private const val SQUASH_GRAPHICS_BEGIN = 767
@@ -29,39 +31,27 @@ private const val LAUNCH_ANIMATION = 4547
* @author Ceikry
*/
@Initializable
class GrandSeedPodHandler : OptionHandler() {
override fun newInstance(arg: Any?): Plugin<Any> {
val def = ItemDefinition.forId(Items.GRAND_SEED_POD_9469)
def.handlers["option:squash"] = this
def.handlers["option:launch"] = this
return this
}
class GrandSeedPodHandler : InteractionListener() {
override fun handle(player: Player?, node: Node?, option: String?): Boolean {
player ?: return false
node ?: return false
option ?: return false
when(option){
"squash" -> {
GameWorld.Pulser.submit(SquashPulse(player))
override fun defineListeners() {
on(Items.GRAND_SEED_POD_9469, ITEM, "squash", "launch"){player, _ ->
when(ContentAPI.getUsedOption(player)){
"launch" -> ContentAPI.submitWorldPulse(LaunchPulse(player))
"squash" -> ContentAPI.submitWorldPulse(SquashPulse(player))
}
"launch" -> {
GameWorld.Pulser.submit(LaunchPulse(player))
}
ContentAPI.removeItem(player, Items.GRAND_SEED_POD_9469, api.Container.INVENTORY)
ContentAPI.lock(player, 50)
return@on true
}
player.inventory.remove(Item(node.id,1))
player.lock()
return true
}
class LaunchPulse(val player: Player): Pulse(){
var counter = 0
override fun pulse(): Boolean {
when(counter++){
1 -> player.visualize(Animation(LAUNCH_ANIMATION),Graphics(LAUNCH_GRAPHICS))
3 -> player.skills.addExperience(Skills.FARMING,100.0)
4 -> GameWorld.Pulser.submit(GliderPulse(2,player,Gliders.TA_QUIR_PRIW)).also { return true }
1 -> ContentAPI.visualize(player, LAUNCH_ANIMATION, LAUNCH_GRAPHICS)
3 -> ContentAPI.rewardXP(player, Skills.FARMING, 100.0)
4 -> ContentAPI.submitWorldPulse(GliderPulse(2,player,Gliders.TA_QUIR_PRIW)).also { return true }
}
return false
}
@@ -71,12 +61,12 @@ class GrandSeedPodHandler : OptionHandler() {
var counter = 0
override fun pulse(): Boolean {
when(counter++){
1 -> player.visualize(Animation(SQUASH_ANIM_BEGIN), Graphics(SQUASH_GRAPHICS_BEGIN))
4 -> player.animator.forceAnimation(Animation(1241))
5 -> player.properties.teleportLocation = Location.create(2464, 3494, 0)
6 -> player.visualize(Animation(1241),Graphics(SQUASH_GRAPHICS_END))
8 -> player.animator.forceAnimation(Animation(SQUASH_ANIM_END)).also { player.skills.setLevel(Skills.FARMING,player.skills.getStaticLevel(Skills.FARMING) - 5) }
9 -> player.unlock().also { return true }
1 -> ContentAPI.visualize(player, SQUASH_ANIM_BEGIN, SQUASH_GRAPHICS_BEGIN)
4 -> ContentAPI.animate(player, 1241, true)
5 -> ContentAPI.teleport(player, Location.create(2464, 3494, 0))
6 -> ContentAPI.visualize(player, anim = 1241, gfx = SQUASH_GRAPHICS_END)
8 -> ContentAPI.animate(player, SQUASH_ANIM_END, true).also { ContentAPI.adjustLevel(player, Skills.FARMING, -5) }
9 -> ContentAPI.unlock(player).also { return true }
}
return false
}
@@ -1,8 +1,10 @@
package rs09.game.interaction.`object`
import api.ContentAPI
import core.game.node.entity.player.link.diary.DiaryType
import core.game.node.entity.player.link.emote.Emotes
import core.game.world.map.RegionManager
import org.rs09.consts.NPCs
import rs09.game.interaction.InteractionListener
/**
@@ -14,15 +16,11 @@ class DemonTauntHandler : InteractionListener(){
override fun defineListeners() {
on(BARS,OBJECT,"taunt-through"){player,_ ->
player.packetDispatch.sendMessage("You taunt the demon, making it growl.")
val localNpcs = RegionManager.getLocalNpcs(player)
player.animator.animate(Emotes.RASPBERRY.animation)
for (npc in localNpcs) {
if (npc.id == 82) {
npc.sendChat("Graaaagh!", 1)
player.faceLocation(npc.location)
}
}
ContentAPI.sendMessage(player, "You taunt the demon, making it growl.")
val demon = ContentAPI.findLocalNPC(player, NPCs.LESSER_DEMON_82) ?: return@on true
ContentAPI.sendChat(demon, "Graaagh!")
ContentAPI.face(demon, player, 3)
ContentAPI.emote(player, Emotes.RASPBERRY)
player.achievementDiaryManager.finishTask(player, DiaryType.LUMBRIDGE, 1, 13)
return@on true
}