diff --git a/game/plugins/src/main/kotlin/gg/rsmod/plugins/content/npcs/man/man_chat.plugin.kts b/game/plugins/src/main/kotlin/gg/rsmod/plugins/content/npcs/man/man_chat.plugin.kts index db2c0d8573..050adc7204 100644 --- a/game/plugins/src/main/kotlin/gg/rsmod/plugins/content/npcs/man/man_chat.plugin.kts +++ b/game/plugins/src/main/kotlin/gg/rsmod/plugins/content/npcs/man/man_chat.plugin.kts @@ -9,6 +9,15 @@ MEN.forEach { man -> on_npc_option(npc = man, option = "talk-to") { player.queue { chat(this) } } + + npc_drop_table(npc = man) { + val map = HashMap() + map[Items.BONES] = 1 + if(world.random(1..10) == 4) { + map[Items.COINS_995] = 100 + } + map + } } suspend fun chat(it: QueueTask) { diff --git a/game/src/main/kotlin/gg/rsmod/game/action/NpcDeathAction.kt b/game/src/main/kotlin/gg/rsmod/game/action/NpcDeathAction.kt index c3a0e99ca2..c2c53a9715 100644 --- a/game/src/main/kotlin/gg/rsmod/game/action/NpcDeathAction.kt +++ b/game/src/main/kotlin/gg/rsmod/game/action/NpcDeathAction.kt @@ -3,6 +3,7 @@ package gg.rsmod.game.action import gg.rsmod.game.fs.def.AnimDef import gg.rsmod.game.model.LockState import gg.rsmod.game.model.attr.KILLER_ATTR +import gg.rsmod.game.model.entity.GroundItem import gg.rsmod.game.model.entity.Npc import gg.rsmod.game.model.entity.Player import gg.rsmod.game.model.queue.QueueTask @@ -34,12 +35,16 @@ object NpcDeathAction { val world = npc.world val deathAnimation = npc.combatDef.deathAnimation val respawnDelay = npc.combatDef.respawnDelay + val killer = npc.damageMap.getMostDamage() - npc.damageMap.getMostDamage()?.let { killer -> - if (killer is Player) { - world.getService(LoggerService::class.java, searchSubclasses = true)?.logNpcKill(killer, npc) + npc.stopMovement() + npc.lock() + + npc.damageMap.getMostDamage()?.let { _killer -> + if (_killer is Player) { + world.getService(LoggerService::class.java, searchSubclasses = true)?.logNpcKill(_killer, npc) } - npc.attr[KILLER_ATTR] = WeakReference(killer) + npc.attr[KILLER_ATTR] = WeakReference(_killer) } world.plugins.executeNpcPreDeath(npc) @@ -56,6 +61,12 @@ object NpcDeathAction { world.plugins.executeNpcDeath(npc) + val drops = world.plugins.executeNpcDropTable(killer, npc.id) + + drops?.forEach { id, amount -> + world.spawn(GroundItem(id, amount, npc.tile, killer as? Player)) + } + if (npc.respawns) { npc.invisible = true npc.reset() diff --git a/game/src/main/kotlin/gg/rsmod/game/plugin/KotlinPlugin.kt b/game/src/main/kotlin/gg/rsmod/game/plugin/KotlinPlugin.kt index 3a1d199b52..b52001e9dd 100644 --- a/game/src/main/kotlin/gg/rsmod/game/plugin/KotlinPlugin.kt +++ b/game/src/main/kotlin/gg/rsmod/game/plugin/KotlinPlugin.kt @@ -516,6 +516,8 @@ abstract class KotlinPlugin(private val r: PluginRepository, val world: World, v */ fun on_item_on_npc(item: Int, npc: Int, plugin: Plugin.() -> Unit) = r.bindItemOnNpc(npc = npc, item = item, plugin = plugin) + fun npc_drop_table(npc: Int, plugin: (Plugin).() -> HashMap?) = r.bindNpcDropTable(npc = npc, plugin = plugin) + companion object { private val METADATA_PATH = Paths.get("./plugins", "configs") } diff --git a/game/src/main/kotlin/gg/rsmod/game/plugin/PluginRepository.kt b/game/src/main/kotlin/gg/rsmod/game/plugin/PluginRepository.kt index 6b3f0742d1..c896b2a4e7 100644 --- a/game/src/main/kotlin/gg/rsmod/game/plugin/PluginRepository.kt +++ b/game/src/main/kotlin/gg/rsmod/game/plugin/PluginRepository.kt @@ -331,6 +331,12 @@ class PluginRepository(val world: World) { */ private val npcDeathPlugins = Int2ObjectOpenHashMap Unit>() + /** + * A list of plugin that will be invoked when an npc dies + * and invokes its drop table + */ + private val npcDropsPlugins = Int2ObjectOpenHashMap HashMap?>() + /** * A map of plugins that occur when an [Event] is triggered. */ @@ -1253,5 +1259,20 @@ class PluginRepository(val world: World) { } } + fun bindNpcDropTable(npc: Int, plugin: Plugin.() -> HashMap?) { + if (npcDropsPlugins.containsKey(npc)) { + val error = java.lang.IllegalStateException("Npc drop table is already bound to a plugin: npc=$npc") + logger.error(error) {} + throw error + } + npcDropsPlugins[npc] = plugin + pluginCount++ + } + + fun executeNpcDropTable(p: Pawn?, npc: Int): HashMap? { + val plugin = npcDropsPlugins[npc] ?: return null + return p?.executePlugin(plugin) + } + companion object : KLogging() } \ No newline at end of file