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.impl.Projectile
import core.game.node.entity.npc.NPC import core.game.node.entity.npc.NPC
import core.game.node.entity.player.Player 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.audio.Audio
import core.game.node.entity.player.link.emote.Emotes 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.entity.skill.gather.SkillingTool
import core.game.node.item.GroundItem import core.game.node.item.GroundItem
import core.game.node.item.GroundItemManager 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.RegionManager
import core.game.world.map.path.Pathfinder import core.game.world.map.path.Pathfinder
import core.game.world.update.flag.context.Animation 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.content.dialogue.DialogueFile
import rs09.game.system.SystemLogger import rs09.game.system.SystemLogger
import rs09.game.world.GameWorld import rs09.game.world.GameWorld
@@ -115,14 +115,21 @@ object ContentAPI {
* Remove an item from a player's inventory * Remove an item from a player's inventory
* @param player the player whose inventory to remove the item from * @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 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 @JvmStatic
fun <T> removeItem(player: Player, item: T): Boolean { fun <T> removeItem(player: Player, item: T, container: Container): Boolean {
item ?: return false item ?: return false
when (item) { val it = when (item) {
is Item -> return player.inventory.remove(item) is Item -> item
is Int -> return player.inventory.remove(Item(item)) is Int -> Item(item)
else -> SystemLogger.logErr("Attempted to pass a non-item and non-int to removeItem") 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 return false
} }
@@ -426,15 +433,21 @@ object ContentAPI {
/** /**
* Plays an animation on the entity * Plays an animation on the entity
* @param entity the entity to animate * @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) * @param forced whether or not to force the animation (usually not necessary)
*/ */
@JvmStatic @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) { if (forced) {
entity.animator.forceAnimation(anim) entity.animator.forceAnimation(animation)
} else { } 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}") 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 method = get(id,type,option) ?: get(option,type) ?: return false
val destOverride = getOverride(type, id, option) ?: getOverride(type,node.id) ?: getOverride(type,option.toLowerCase()) val destOverride = getOverride(type, id, option) ?: getOverride(type,node.id) ?: getOverride(type,option.toLowerCase())
player.setAttribute("interact:option", option)
if(type != 0) { if(type != 0) {
if(player.locks.isMovementLocked) return false if(player.locks.isMovementLocked) return false
player.pulseManager.run(object : MovementPulse(player, node, flag, destOverride) { player.pulseManager.run(object : MovementPulse(player, node, flag, destOverride) {
@@ -1,5 +1,6 @@
package rs09.game.interaction.item package rs09.game.interaction.item
import api.ContentAPI
import rs09.game.interaction.InteractionListener import rs09.game.interaction.InteractionListener
/** /**
@@ -13,8 +14,8 @@ class BraceletOfClayPlugin : InteractionListener() {
override fun defineListeners() { override fun defineListeners() {
on(BRACELET,ITEM,"operate"){player,node -> on(BRACELET,ITEM,"operate"){player,node ->
var charge = node.asItem().charge var charge = ContentAPI.getCharge(node)
if (charge > 28) charge = 28 if (charge > 28) ContentAPI.setCharge(node, 28).also { charge = 28 }
player.sendMessage("You have $charge uses left.") player.sendMessage("You have $charge uses left.")
return@on true return@on true
} }
@@ -1,5 +1,6 @@
package rs09.game.interaction.item package rs09.game.interaction.item
import api.ContentAPI
import core.game.node.Node import core.game.node.Node
import core.game.node.entity.player.Player import core.game.node.entity.player.Player
import core.game.node.item.GroundItemManager import core.game.node.item.GroundItemManager
@@ -42,15 +43,13 @@ class CulChestItems: InteractionListener() {
} }
fun alchemize(player: Player, node: Node){ fun alchemize(player: Player, node: Node){
val amount = player.inventory.getAmount(node.id) + player.equipment.getAmount(node.id) val amount = ContentAPI.amountInInventory(player, node.id) + ContentAPI.amountInEquipment(player, node.id)
val coins = amount * node.asItem().definition.value val coins = amount * ContentAPI.itemDefinition(node.id).value
player.inventory.remove(Item(node.id,player.inventory.getAmount(node.id))) ContentAPI.removeAll(player, node.id, api.Container.INVENTORY)
player.equipment.remove(Item(node.id)) ContentAPI.removeItem(player, node.id, api.Container.EQUIPMENT)
if(!player.inventory.add(Item(995,coins))){ ContentAPI.addItemOrDrop(player, 995, coins)
GroundItemManager.create(Item(995,coins),player)
}
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 package rs09.game.interaction.item
import api.ContentAPI
import core.cache.def.impl.ItemDefinition import core.cache.def.impl.ItemDefinition
import core.game.content.global.travel.glider.GliderPulse import core.game.content.global.travel.glider.GliderPulse
import core.game.content.global.travel.glider.Gliders 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.Initializable
import core.plugin.Plugin import core.plugin.Plugin
import org.rs09.consts.Items import org.rs09.consts.Items
import rs09.game.interaction.InteractionListener
import rs09.game.world.GameWorld import rs09.game.world.GameWorld
private const val SQUASH_GRAPHICS_BEGIN = 767 private const val SQUASH_GRAPHICS_BEGIN = 767
@@ -29,39 +31,27 @@ private const val LAUNCH_ANIMATION = 4547
* @author Ceikry * @author Ceikry
*/ */
@Initializable @Initializable
class GrandSeedPodHandler : OptionHandler() { class GrandSeedPodHandler : InteractionListener() {
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
}
override fun handle(player: Player?, node: Node?, option: String?): Boolean { override fun defineListeners() {
player ?: return false on(Items.GRAND_SEED_POD_9469, ITEM, "squash", "launch"){player, _ ->
node ?: return false when(ContentAPI.getUsedOption(player)){
option ?: return false "launch" -> ContentAPI.submitWorldPulse(LaunchPulse(player))
when(option){ "squash" -> ContentAPI.submitWorldPulse(SquashPulse(player))
"squash" -> {
GameWorld.Pulser.submit(SquashPulse(player))
} }
"launch" -> { ContentAPI.removeItem(player, Items.GRAND_SEED_POD_9469, api.Container.INVENTORY)
GameWorld.Pulser.submit(LaunchPulse(player)) ContentAPI.lock(player, 50)
return@on true
} }
}
player.inventory.remove(Item(node.id,1))
player.lock()
return true
} }
class LaunchPulse(val player: Player): Pulse(){ class LaunchPulse(val player: Player): Pulse(){
var counter = 0 var counter = 0
override fun pulse(): Boolean { override fun pulse(): Boolean {
when(counter++){ when(counter++){
1 -> player.visualize(Animation(LAUNCH_ANIMATION),Graphics(LAUNCH_GRAPHICS)) 1 -> ContentAPI.visualize(player, LAUNCH_ANIMATION, LAUNCH_GRAPHICS)
3 -> player.skills.addExperience(Skills.FARMING,100.0) 3 -> ContentAPI.rewardXP(player, Skills.FARMING, 100.0)
4 -> GameWorld.Pulser.submit(GliderPulse(2,player,Gliders.TA_QUIR_PRIW)).also { return true } 4 -> ContentAPI.submitWorldPulse(GliderPulse(2,player,Gliders.TA_QUIR_PRIW)).also { return true }
} }
return false return false
} }
@@ -71,12 +61,12 @@ class GrandSeedPodHandler : OptionHandler() {
var counter = 0 var counter = 0
override fun pulse(): Boolean { override fun pulse(): Boolean {
when(counter++){ when(counter++){
1 -> player.visualize(Animation(SQUASH_ANIM_BEGIN), Graphics(SQUASH_GRAPHICS_BEGIN)) 1 -> ContentAPI.visualize(player, SQUASH_ANIM_BEGIN, SQUASH_GRAPHICS_BEGIN)
4 -> player.animator.forceAnimation(Animation(1241)) 4 -> ContentAPI.animate(player, 1241, true)
5 -> player.properties.teleportLocation = Location.create(2464, 3494, 0) 5 -> ContentAPI.teleport(player, Location.create(2464, 3494, 0))
6 -> player.visualize(Animation(1241),Graphics(SQUASH_GRAPHICS_END)) 6 -> ContentAPI.visualize(player, anim = 1241, gfx = SQUASH_GRAPHICS_END)
8 -> player.animator.forceAnimation(Animation(SQUASH_ANIM_END)).also { player.skills.setLevel(Skills.FARMING,player.skills.getStaticLevel(Skills.FARMING) - 5) } 8 -> ContentAPI.animate(player, SQUASH_ANIM_END, true).also { ContentAPI.adjustLevel(player, Skills.FARMING, -5) }
9 -> player.unlock().also { return true } 9 -> ContentAPI.unlock(player).also { return true }
} }
return false return false
} }
@@ -1,8 +1,10 @@
package rs09.game.interaction.`object` package rs09.game.interaction.`object`
import api.ContentAPI
import core.game.node.entity.player.link.diary.DiaryType import core.game.node.entity.player.link.diary.DiaryType
import core.game.node.entity.player.link.emote.Emotes import core.game.node.entity.player.link.emote.Emotes
import core.game.world.map.RegionManager import core.game.world.map.RegionManager
import org.rs09.consts.NPCs
import rs09.game.interaction.InteractionListener import rs09.game.interaction.InteractionListener
/** /**
@@ -14,15 +16,11 @@ class DemonTauntHandler : InteractionListener(){
override fun defineListeners() { override fun defineListeners() {
on(BARS,OBJECT,"taunt-through"){player,_ -> on(BARS,OBJECT,"taunt-through"){player,_ ->
player.packetDispatch.sendMessage("You taunt the demon, making it growl.") ContentAPI.sendMessage(player, "You taunt the demon, making it growl.")
val localNpcs = RegionManager.getLocalNpcs(player) val demon = ContentAPI.findLocalNPC(player, NPCs.LESSER_DEMON_82) ?: return@on true
player.animator.animate(Emotes.RASPBERRY.animation) ContentAPI.sendChat(demon, "Graaagh!")
for (npc in localNpcs) { ContentAPI.face(demon, player, 3)
if (npc.id == 82) { ContentAPI.emote(player, Emotes.RASPBERRY)
npc.sendChat("Graaaagh!", 1)
player.faceLocation(npc.location)
}
}
player.achievementDiaryManager.finishTask(player, DiaryType.LUMBRIDGE, 1, 13) player.achievementDiaryManager.finishTask(player, DiaryType.LUMBRIDGE, 1, 13)
return@on true return@on true
} }