diff --git a/data/spawns/drops.yml b/data/spawns/drops.yml index da5f3fc81..6175018a3 100644 --- a/data/spawns/drops.yml +++ b/data/spawns/drops.yml @@ -1695,4 +1695,9 @@ monk_of_zamorak_drop_table: - roll: 20 drops: - id: zamorak_robe_bottom - - id: zamorak_robe_top \ No newline at end of file + - id: zamorak_robe_top +human_pickpocket: + type: all + drops: + - id: coins + amount: 3 diff --git a/game/src/main/kotlin/world/gregs/voidps/world/activity/skill/thieving/Pickpocketing.kts b/game/src/main/kotlin/world/gregs/voidps/world/activity/skill/thieving/Pickpocketing.kts index 935ce1fc4..e395a3def 100644 --- a/game/src/main/kotlin/world/gregs/voidps/world/activity/skill/thieving/Pickpocketing.kts +++ b/game/src/main/kotlin/world/gregs/voidps/world/activity/skill/thieving/Pickpocketing.kts @@ -19,10 +19,11 @@ import world.gregs.voidps.engine.entity.character.player.skill.exp.exp import world.gregs.voidps.engine.entity.character.player.skill.level.Level.has import world.gregs.voidps.engine.entity.character.player.skill.level.Level.success import world.gregs.voidps.engine.entity.character.setAnimation -import world.gregs.voidps.engine.entity.item.drop.DropTable import world.gregs.voidps.engine.entity.item.drop.DropTables +import world.gregs.voidps.engine.entity.item.drop.ItemDrop import world.gregs.voidps.engine.inject import world.gregs.voidps.engine.inv.inventory +import world.gregs.voidps.engine.inv.transact.Transaction import world.gregs.voidps.engine.inv.transact.TransactionError import world.gregs.voidps.engine.inv.transact.operation.AddItem.add import world.gregs.voidps.engine.queue.softQueue @@ -35,10 +36,6 @@ val dropTables: DropTables by inject() val logger = InlineLogger() npcOperate("Pickpocket") { - if (player.inventory.isFull()) { - player.inventoryFull() - return@npcOperate - } if (player.hasClock("food_delay") || player.hasClock("action_delay")) { // Should action_delay and food_delay be the same?? return@npcOperate } @@ -46,17 +43,24 @@ npcOperate("Pickpocket") { if (!player.has(Skill.Thieving, pocket.level)) { return@npcOperate } + val success = success(player.levels.get(Skill.Thieving), pocket.chance) + val drops = getLoot(target) ?: emptyList() + if (success && !canLoot(player, drops)) { + return@npcOperate + } player.start("delay", 3) player.start("movement_delay", 3) val name = target.def.name player.message("You attempt to pick the ${name}'s pocket.", ChatType.Filter) target.start("movement_delay", 1) player.softQueue("pick-pocket", 2) { - if (success(player.levels.get(Skill.Thieving), pocket.chance)) { + if (success) { + player.inventory.transaction { + addLoot(drops) + } player.setAnimation("pick_pocket") player.message("You pick the ${name}'s pocket.", ChatType.Filter) player.exp(Skill.Thieving, pocket.xp) - giveLoot(player, target) } else { target.face(player) target.forceChat = pocket.caughtMessage @@ -67,24 +71,30 @@ npcOperate("Pickpocket") { } } -fun giveLoot(player: Player, target: NPC) { - var table: DropTable? = dropTables.get("${target.id}_pickpocket") - if (table == null) { - table = dropTables.get("${target.race}_pickpocket") - } - if (table == null) { - return +fun getLoot(target: NPC): List? { + val table = dropTables.get("${target.id}_pickpocket") ?: dropTables.get("${target.race}_pickpocket") + return table?.role(members = World.members) +} + +fun canLoot(player: Player, drops: List): Boolean { + val transaction = player.inventory.transaction + transaction.start() + transaction.addLoot(drops) + transaction.revert() + when (transaction.error) { + is TransactionError.Full -> player.inventoryFull() + TransactionError.None -> return true + else -> logger.warn { "Unable to add pickpocket loot $player $drops" } } - val loot = table.role(members = World.members) - player.inventory.transaction { - for (drop in loot) { - val item = drop.toItem() - add(item.id, item.amount) + return false +} + +fun Transaction.addLoot(drops: List) { + for (drop in drops) { + val item = drop.toItem() + if (item.isEmpty()) { + continue } - } - when (player.inventory.transaction.error) { - is TransactionError.Full -> player.inventoryFull() - TransactionError.None -> {} - else -> logger.warn { "Unable to add pickpocket loot $player $loot" } + add(item.id, item.amount) } } \ No newline at end of file