From 870d4b63702df33bf14c01bd297fb15f3ad74b63 Mon Sep 17 00:00:00 2001 From: Syntax Date: Sat, 27 Apr 2024 19:59:07 +0100 Subject: [PATCH 1/9] * Add burrowing animation for `Giant Mole` * Add component ID to `warning_dark` interface * Add `level_one_darkness`, `level_two_darkness`, `level_three_darkness` overlays for different strength of darkness * Add stats for `Giant Mole` in `npcs.yml` * Add new area called `giant_mole_lair` to `areas.yml` * Add `Giant Mole` spawn to `npc-spawns.yml` * Add `GiantMole.kts` to handle `Giant Moles` fight mechanics --- data/definitions/animations.yml | 2 + data/definitions/interfaces.yml | 16 +- data/definitions/npcs.yml | 13 +- data/map/areas.yml | 7 +- data/spawns/npc-spawns.yml | 2 + .../entity/npc/combat/type/GiantMole.kts | 145 ++++++++++++++++++ 6 files changed, 182 insertions(+), 3 deletions(-) create mode 100644 game/src/main/kotlin/world/gregs/voidps/world/interact/entity/npc/combat/type/GiantMole.kts diff --git a/data/definitions/animations.yml b/data/definitions/animations.yml index 371dbd3f0f..29e404b308 100644 --- a/data/definitions/animations.yml +++ b/data/definitions/animations.yml @@ -1668,3 +1668,5 @@ fletching_string_steel_crossbow: 6674 fletching_string_mithril_crossbow: 6675 fletching_string_adamant_crossbow: 6676 fletching_string_rune_crossbow: 6677 +dig_with_spade: 830 +giant_mole_burrow: 3314 \ No newline at end of file diff --git a/data/definitions/interfaces.yml b/data/definitions/interfaces.yml index a4c729c711..039e4a87bd 100644 --- a/data/definitions/interfaces.yml +++ b/data/definitions/interfaces.yml @@ -1756,7 +1756,12 @@ dialogue_multi2_mes: type: dialogue_box warning_spiders: 560 warning_kalphite_queen: 561 -warning_dark: 562 +warning_dark: + id: 562 + type: main_screen + components: + proceed: 17 + stayout: 18 warning_building_mode: 563 warning_archers: 564 warning_desert: 565 @@ -2517,3 +2522,12 @@ fade_in: fade_out_smoke: id: 162 type: overlay +level_one_darkness: + id: 97 + type: overlay +level_two_darkness: + id: 98 + type: overlay +level_three_darkness: + id: 96 + type: overlay diff --git a/data/definitions/npcs.yml b/data/definitions/npcs.yml index f5e75b5da2..b4845626c4 100644 --- a/data/definitions/npcs.yml +++ b/data/definitions/npcs.yml @@ -1829,4 +1829,15 @@ al_the_camel: race: camel large_head: true wander_radius: 4 - examine: "A camel who has the soul of a poet." \ No newline at end of file + examine: "A camel who has the soul of a poet." +giant_mole: # this is the wrong ID for giant mole still need to find the correct one | burrow anim id found | coming up from ground not found + id: 3340 + hitpoints: 2000 + att: 200 + str: 200 + def: 200 + max_hit_melee: 210 + style: crush + respawn_delay: 16 + wander_radius: 5 + examine: "Holy Mole-y!" \ No newline at end of file diff --git a/data/map/areas.yml b/data/map/areas.yml index 37fede159a..9d293ff016 100644 --- a/data/map/areas.yml +++ b/data/map/areas.yml @@ -977,4 +977,9 @@ camulet_teleport: area: x: [ 3192, 3194 ] y: [ 2924, 2926 ] - tags: [ teleport ] \ No newline at end of file + tags: [ teleport ] +giant_mole_lair: + area: + x: [ 1730, 1791 ] + y: [ 5144, 5229 ] + tags: [ multi_combat ] \ No newline at end of file diff --git a/data/spawns/npc-spawns.yml b/data/spawns/npc-spawns.yml index 78ea382e06..31e7afdc12 100644 --- a/data/spawns/npc-spawns.yml +++ b/data/spawns/npc-spawns.yml @@ -1,5 +1,7 @@ # 6743 - { id: banker_fist_of_guthix, x: 1705, y: 5599 } +# 6993 +- { id: giant_mole, x: 1762, y: 5185 } # 7243 - { id: rat, x: 1816, y: 4836, level: 1, members: true } - { id: rat, x: 1815, y: 4832, members: true } diff --git a/game/src/main/kotlin/world/gregs/voidps/world/interact/entity/npc/combat/type/GiantMole.kts b/game/src/main/kotlin/world/gregs/voidps/world/interact/entity/npc/combat/type/GiantMole.kts new file mode 100644 index 0000000000..5c66d67f75 --- /dev/null +++ b/game/src/main/kotlin/world/gregs/voidps/world/interact/entity/npc/combat/type/GiantMole.kts @@ -0,0 +1,145 @@ +package world.gregs.voidps.world.interact.entity.npc.combat.type + +import com.github.michaelbull.logging.InlineLogger +import world.gregs.voidps.engine.client.ui.close +import world.gregs.voidps.engine.client.ui.closeInterfaces +import world.gregs.voidps.engine.client.ui.event.adminCommand +import world.gregs.voidps.engine.client.ui.interfaceOption +import world.gregs.voidps.engine.client.ui.open +import world.gregs.voidps.engine.data.definition.AreaDefinitions +import world.gregs.voidps.engine.entity.World +import world.gregs.voidps.engine.entity.character.mode.move.enterArea +import world.gregs.voidps.engine.entity.character.mode.move.exitArea +import world.gregs.voidps.engine.entity.character.move.tele +import world.gregs.voidps.engine.entity.character.npc.NPC +import world.gregs.voidps.engine.entity.character.player.Player +import world.gregs.voidps.engine.entity.character.player.skill.Skill +import world.gregs.voidps.engine.entity.character.setAnimation +import world.gregs.voidps.engine.entity.playerSpawn +import world.gregs.voidps.engine.inject +import world.gregs.voidps.engine.inv.inventory +import world.gregs.voidps.engine.map.collision.random +import world.gregs.voidps.type.Tile +import world.gregs.voidps.world.interact.entity.combat.* +import world.gregs.voidps.world.interact.entity.combat.hit.combatAttack +import world.gregs.voidps.world.interact.entity.player.equip.inventoryOption +import kotlin.random.Random + +val logger = InlineLogger() +val areas: AreaDefinitions by inject() + +//TODO: Add drop table +//TODO: inventory update: if the players light source get's turned off need to reapply darnkess overlay +//TODO: find correct giant mole NPC ID +//TODO: make giantMoleLair cover the whole area + +// list of tiles where the mole hills are located. +val acceptedTiles = listOf( + Tile(3005, 3376, 0), + Tile(2999, 3375, 0), + Tile(2996, 3377, 0), + Tile(2989, 3378, 0) +) + +val giantMoleLair = areas["giant_mole_lair"] +val initialCaveTile: Tile = Tile(1752, 5237, 0) + +//temp +var commandLocation: Tile = Tile.EMPTY + +adminCommand("tomole") { + player.tele(commandLocation) +} +//temp + +inventoryOption("Dig") { + val playerTile: Tile = player.tile + if(!acceptedTiles.contains(playerTile)) { + return@inventoryOption + } + player.setAnimation("dig_with_spade") + player.open("warning_dark") +} + +interfaceOption(component = "proceed", id = "warning_dark") { + player.tele(initialCaveTile, clearInterfaces = true) +} + +interfaceOption(component = "stayout", id = "warning_dark") { + player.closeInterfaces() +} + +combatAttack { + val npc = target as NPC + if(npc.id == "giant_mole") { + val currentHealth = npc.levels.get(Skill.Constitution) + if(shouldBurrowAway(currentHealth) && !World.timers.contains("await_mole_burrowing")) { + if (it.fightStyle == "magic" && damage != 0) { + giantMoleBurrow(npc) + } else if (it.fightStyle != "magic") { + giantMoleBurrow(npc) + } + } + } +} + +//TODO: theres a small chance that when the mole burrows to throws dirt on the clients screen extinguishing some light sources +fun giantMoleBurrow(mole: NPC) { + mole.attackers.clear() //stop players attacking while mole is burrowing away. N: maybe a for loop getting all players attacking and setting their target to null is better? + mole.setAnimation("giant_mole_burrow") + World.queue("await_mole_burrowing", 3) { + val newLocation = giantMoleLair.random(mole) + commandLocation = newLocation!! + mole.tele(newLocation) + } +} + +// 15% maybe too high +fun shouldThrowDirt(): Boolean { + val dirtChance = Random.nextInt(0, 100) + return dirtChance <= 15 +} + +//if the moles health is between 50% and 5% percent give a 25% to burrow away +fun shouldBurrowAway(health: Int): Boolean { + val maxHealth = 2000 + val minThreshold = maxHealth * 0.05 + val maxThreshold = maxHealth * 0.50 + if (health in minThreshold.toInt()..maxThreshold.toInt()) { + val shouldBurrow = Random.nextInt(0, 100) + return shouldBurrow <= 25 + } + return false +} + +enterArea("giant_mole_lair") { + if(!hasLightSource(player)) { + player.open("level_three_darkness") + } +} + +exitArea("giant_mole_lair") { + if(player.interfaces.contains("level_three_darkness")) { + player.close("level_three_darkness") + } +} + +playerSpawn { player -> + if(giantMoleLair.contains(player.tile)) { + if(!hasLightSource(player)) { + player.open("level_three_darkness") + } + } +} + +// check player inventory to see if they have a lit light source. +fun hasLightSource(player: Player): Boolean { + val playerItems = player.inventory.items + + for (item in playerItems) { + if (item.id.contains("lantern_lit") || item.id.contains("candle_lit")) { + return true + } + } + return false +} \ No newline at end of file From 80e7d75361e8dd700b04e3eff425b224337ab64f Mon Sep 17 00:00:00 2001 From: Syntax Date: Sun, 28 Apr 2024 10:43:49 +0100 Subject: [PATCH 2/9] * Add `attack`, `hit`, and `death` animation for Giant Mole in `animations.yml` * Add `dirt_on_screen` overlay to `interfaces.yml` * Add `race: giant_mole` to `Giant Mole` in `npcs.yml` * Add the `giant_mole_lair_escape_rope` object to `objects.yml` * Extend boundary for `giant_mole_lair` to cover that whole area, before the north and south parts of the lair weren't included in the area * Add `objectOperate` to `GiantMole.kts` to handle when a player climbs the rope. --- data/definitions/animations.yml | 5 +- data/definitions/interfaces.yml | 3 + data/definitions/npcs.yml | 1 + data/definitions/objects.yml | 4 +- data/map/areas.yml | 6 +- .../entity/npc/combat/type/GiantMole.kts | 62 +++++++++++++++---- 6 files changed, 63 insertions(+), 18 deletions(-) diff --git a/data/definitions/animations.yml b/data/definitions/animations.yml index 29e404b308..7c6f3c2a99 100644 --- a/data/definitions/animations.yml +++ b/data/definitions/animations.yml @@ -1669,4 +1669,7 @@ fletching_string_mithril_crossbow: 6675 fletching_string_adamant_crossbow: 6676 fletching_string_rune_crossbow: 6677 dig_with_spade: 830 -giant_mole_burrow: 3314 \ No newline at end of file +giant_mole_burrow: 3314 +giant_mole_attack: 3312 +giant_mole_hit: 3311 +giant_mole_death: 3310 \ No newline at end of file diff --git a/data/definitions/interfaces.yml b/data/definitions/interfaces.yml index 039e4a87bd..4c75a5aed6 100644 --- a/data/definitions/interfaces.yml +++ b/data/definitions/interfaces.yml @@ -2531,3 +2531,6 @@ level_two_darkness: level_three_darkness: id: 96 type: overlay +dirt_on_screen: + id: 226 + type: overlay diff --git a/data/definitions/npcs.yml b/data/definitions/npcs.yml index b4845626c4..c0fd247681 100644 --- a/data/definitions/npcs.yml +++ b/data/definitions/npcs.yml @@ -1838,6 +1838,7 @@ giant_mole: # this is the wrong ID for giant mole still need to find the correct def: 200 max_hit_melee: 210 style: crush + race: giant_mole respawn_delay: 16 wander_radius: 5 examine: "Holy Mole-y!" \ No newline at end of file diff --git a/data/definitions/objects.yml b/data/definitions/objects.yml index b9c01941dc..ca79ed8d05 100644 --- a/data/definitions/objects.yml +++ b/data/definitions/objects.yml @@ -11703,4 +11703,6 @@ prayer_altar_zaros: examine: "Shrine to the glory of Zaros." prayer_altar_warped_construction: id: 55667 - examine: "A shrine for the faithful to worship at." \ No newline at end of file + examine: "A shrine for the faithful to worship at." +giant_mole_lair_escape_rope: + id: 12230 \ No newline at end of file diff --git a/data/map/areas.yml b/data/map/areas.yml index 9d293ff016..bae216f773 100644 --- a/data/map/areas.yml +++ b/data/map/areas.yml @@ -980,6 +980,6 @@ camulet_teleport: tags: [ teleport ] giant_mole_lair: area: - x: [ 1730, 1791 ] - y: [ 5144, 5229 ] - tags: [ multi_combat ] \ No newline at end of file + x: [ 1717, 1801 ] + y: [ 5123, 5252 ] + tags: [ boss ] \ No newline at end of file diff --git a/game/src/main/kotlin/world/gregs/voidps/world/interact/entity/npc/combat/type/GiantMole.kts b/game/src/main/kotlin/world/gregs/voidps/world/interact/entity/npc/combat/type/GiantMole.kts index 5c66d67f75..1eb1676166 100644 --- a/game/src/main/kotlin/world/gregs/voidps/world/interact/entity/npc/combat/type/GiantMole.kts +++ b/game/src/main/kotlin/world/gregs/voidps/world/interact/entity/npc/combat/type/GiantMole.kts @@ -13,11 +13,14 @@ import world.gregs.voidps.engine.entity.character.mode.move.exitArea import world.gregs.voidps.engine.entity.character.move.tele import world.gregs.voidps.engine.entity.character.npc.NPC import world.gregs.voidps.engine.entity.character.player.Player +import world.gregs.voidps.engine.entity.character.player.Players import world.gregs.voidps.engine.entity.character.player.skill.Skill import world.gregs.voidps.engine.entity.character.setAnimation +import world.gregs.voidps.engine.entity.obj.objectOperate import world.gregs.voidps.engine.entity.playerSpawn import world.gregs.voidps.engine.inject import world.gregs.voidps.engine.inv.inventory +import world.gregs.voidps.engine.inv.transact.operation.ReplaceItem.replace import world.gregs.voidps.engine.map.collision.random import world.gregs.voidps.type.Tile import world.gregs.voidps.world.interact.entity.combat.* @@ -27,11 +30,10 @@ import kotlin.random.Random val logger = InlineLogger() val areas: AreaDefinitions by inject() +val players: Players by inject() //TODO: Add drop table //TODO: inventory update: if the players light source get's turned off need to reapply darnkess overlay -//TODO: find correct giant mole NPC ID -//TODO: make giantMoleLair cover the whole area // list of tiles where the mole hills are located. val acceptedTiles = listOf( @@ -60,6 +62,11 @@ inventoryOption("Dig") { player.setAnimation("dig_with_spade") player.open("warning_dark") } +// teleport player to random mole hill +objectOperate("Climb", "giant_mole_lair_escape_rope") { + player.setAnimation("climb_up") + player.tele(acceptedTiles.random()) +} interfaceOption(component = "proceed", id = "warning_dark") { player.tele(initialCaveTile, clearInterfaces = true) @@ -73,34 +80,63 @@ combatAttack { val npc = target as NPC if(npc.id == "giant_mole") { val currentHealth = npc.levels.get(Skill.Constitution) - if(shouldBurrowAway(currentHealth) && !World.timers.contains("await_mole_burrowing")) { - if (it.fightStyle == "magic" && damage != 0) { - giantMoleBurrow(npc) - } else if (it.fightStyle != "magic") { - giantMoleBurrow(npc) - } + var shouldBurrow = false + if (it.fightStyle == "magic" && damage != 0) { + shouldBurrow = shouldBurrowAway(currentHealth) + } else if (it.fightStyle != "magic") { + shouldBurrow = shouldBurrowAway(currentHealth) + } + if(shouldBurrow && !World.timers.contains("await_mole_burrowing")) { + giantMoleBurrow(npc) } } } -//TODO: theres a small chance that when the mole burrows to throws dirt on the clients screen extinguishing some light sources fun giantMoleBurrow(mole: NPC) { + if(shouldThrowDirt()) { + handleDirtOnScreen(mole.tile) + } mole.attackers.clear() //stop players attacking while mole is burrowing away. N: maybe a for loop getting all players attacking and setting their target to null is better? mole.setAnimation("giant_mole_burrow") - World.queue("await_mole_burrowing", 3) { + World.queue("await_mole_burrowing", 2) { val newLocation = giantMoleLair.random(mole) commandLocation = newLocation!! mole.tele(newLocation) } } -// 15% maybe too high +// 13% chance to throw dirt on players screen fun shouldThrowDirt(): Boolean { val dirtChance = Random.nextInt(0, 100) - return dirtChance <= 15 + return dirtChance <= 13 +} + +fun handleDirtOnScreen(moleTile: Tile) { + val nearMole = mutableListOf() + for (tile in moleTile.toCuboid(5)) { + for (player in players[tile]) { + nearMole.add(player) + } + } + for (player in nearMole) { + player.open("dirt_on_screen") + val playerInventory = player.inventory.items + for (item in playerInventory) { + if (item.id.contains("candle_lit")) { + val newItem = item.id.replace("_lit", "") + player.inventory.transaction { + replace(item.id, newItem) + } + } + } + } + World.queue("dirt_on_screen_timer_player", 3) { + for (player in nearMole) { + player.close("dirt_on_screen") + } + } } -//if the moles health is between 50% and 5% percent give a 25% to burrow away fun shouldBurrowAway(health: Int): Boolean { val maxHealth = 2000 val minThreshold = maxHealth * 0.05 From 37086eacc0e118e0986f1f8b74354406e5e6bf82 Mon Sep 17 00:00:00 2001 From: Syntax Date: Mon, 29 Apr 2024 19:55:13 +0100 Subject: [PATCH 3/9] * Add animation `dirt_projectile` to `animation.yml` * Add Graphic `burrow_dust` to `graphics.yml` * Add `giant_mole_spawn_area` to `areas.yml` This seems to fix the issues with the mole spawning outside the playing area due to the north and south sides of the lair having walkable tiles outside the playable space. * Add common drops for `giant_mole` to `drops.yml` * Add the mechanic that allows the `giant mole` to burrow with a small chance to throw dirt on the players screen and extinguish any naked flames (candles) * Changed the percentage of the `giant mole` burrowing chance back to 25% --- data/definitions/animations.yml | 3 +- data/definitions/graphics.yml | 3 +- data/map/areas.yml | 5 ++ data/spawns/drops.yml | 73 ++++++++++++++++++- .../entity/npc/combat/type/GiantMole.kts | 48 +++++++++--- 5 files changed, 119 insertions(+), 13 deletions(-) diff --git a/data/definitions/animations.yml b/data/definitions/animations.yml index 7c6f3c2a99..7c255d849d 100644 --- a/data/definitions/animations.yml +++ b/data/definitions/animations.yml @@ -1672,4 +1672,5 @@ dig_with_spade: 830 giant_mole_burrow: 3314 giant_mole_attack: 3312 giant_mole_hit: 3311 -giant_mole_death: 3310 \ No newline at end of file +giant_mole_death: 3310 +dirt_Projectile: 570 \ No newline at end of file diff --git a/data/definitions/graphics.yml b/data/definitions/graphics.yml index 284cec2563..cdcd570a51 100644 --- a/data/definitions/graphics.yml +++ b/data/definitions/graphics.yml @@ -1480,4 +1480,5 @@ dragon_breath_shock: delay: 51 flight_time: [ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20 ] teleport_jewellery: 1684 -teleport_pharaohs_sceptre: 715 \ No newline at end of file +teleport_pharaohs_sceptre: 715 +burrow_dust: 571 \ No newline at end of file diff --git a/data/map/areas.yml b/data/map/areas.yml index bae216f773..8ae3c3fc0d 100644 --- a/data/map/areas.yml +++ b/data/map/areas.yml @@ -982,4 +982,9 @@ giant_mole_lair: area: x: [ 1717, 1801 ] y: [ 5123, 5252 ] + tags: [ boss ] +giant_mole_spawn_area: + area: + x: [ 1733, 1788 ] + y: [ 5150, 5223 ] tags: [ boss ] \ No newline at end of file diff --git a/data/spawns/drops.yml b/data/spawns/drops.yml index 896d07d266..eec4ca1a1e 100644 --- a/data/spawns/drops.yml +++ b/data/spawns/drops.yml @@ -889,4 +889,75 @@ human_drop_table: drops: - type: all drops: - - id: bones \ No newline at end of file + - id: bones +giant_mole: + type: all + drops: + - drops: + - id: big_bones + - id: mole_claw + - id: mole_skin + amount: 1-3 + - roll: 6 + drops: + - id: air_rune + amount: 105 + chance: 1 + - id: blood_rune + amount: 15 + chance: 1 + - roll: 11 + drops: + - id: fire_rune + amount: 105 + chance: 1 + - roll: 12 + drops: + - id: adamant_longsword + chance: 1 + - id: iron_arrow + amount: 690 + chance: 1 + - id: yew_logs_noted + amount: 100 + chance: 1 + - roll: 14 + drops: + - id: mithril_platebody + chance: 1 + - roll: 18 + drops: + - id: amulet_of_strength + chance: 1 + - roll: 25 + drops: + - id: law_rune + amount: 15 + chance: 1 + - roll: 32 + drops: + - id: shark + amount: 4 + chance: 1 + - roll: 42 + drops: + - id: mithril_bar + chance: 1 + - id: death_rune + amount: 7 + chance: 1 + - roll: 64 + drops: + - id: mithril_hatchet + chance: 1 + - id: iron_ore_noted + amount: 100 + chance: 1 + - roll: 128 + drops: + - id: mithril_battleaxe + chance: 1 + - id: rune_med_helm + chance: 1 + - id: oyster_pearls + chance: 1 \ No newline at end of file diff --git a/game/src/main/kotlin/world/gregs/voidps/world/interact/entity/npc/combat/type/GiantMole.kts b/game/src/main/kotlin/world/gregs/voidps/world/interact/entity/npc/combat/type/GiantMole.kts index 1eb1676166..0c0f53b498 100644 --- a/game/src/main/kotlin/world/gregs/voidps/world/interact/entity/npc/combat/type/GiantMole.kts +++ b/game/src/main/kotlin/world/gregs/voidps/world/interact/entity/npc/combat/type/GiantMole.kts @@ -8,6 +8,8 @@ import world.gregs.voidps.engine.client.ui.interfaceOption import world.gregs.voidps.engine.client.ui.open import world.gregs.voidps.engine.data.definition.AreaDefinitions import world.gregs.voidps.engine.entity.World +import world.gregs.voidps.engine.entity.character.face +import world.gregs.voidps.engine.entity.character.facing import world.gregs.voidps.engine.entity.character.mode.move.enterArea import world.gregs.voidps.engine.entity.character.mode.move.exitArea import world.gregs.voidps.engine.entity.character.move.tele @@ -22,9 +24,11 @@ import world.gregs.voidps.engine.inject import world.gregs.voidps.engine.inv.inventory import world.gregs.voidps.engine.inv.transact.operation.ReplaceItem.replace import world.gregs.voidps.engine.map.collision.random +import world.gregs.voidps.type.Direction import world.gregs.voidps.type.Tile import world.gregs.voidps.world.interact.entity.combat.* import world.gregs.voidps.world.interact.entity.combat.hit.combatAttack +import world.gregs.voidps.world.interact.entity.gfx.areaGraphic import world.gregs.voidps.world.interact.entity.player.equip.inventoryOption import kotlin.random.Random @@ -44,6 +48,7 @@ val acceptedTiles = listOf( ) val giantMoleLair = areas["giant_mole_lair"] +val gianMoleSpawns = areas["giant_mole_spawn_area"] val initialCaveTile: Tile = Tile(1752, 5237, 0) //temp @@ -62,7 +67,7 @@ inventoryOption("Dig") { player.setAnimation("dig_with_spade") player.open("warning_dark") } -// teleport player to random mole hill + objectOperate("Climb", "giant_mole_lair_escape_rope") { player.setAnimation("climb_up") player.tele(acceptedTiles.random()) @@ -93,15 +98,38 @@ combatAttack { } fun giantMoleBurrow(mole: NPC) { - if(shouldThrowDirt()) { - handleDirtOnScreen(mole.tile) + mole.attackers.clear() + var tileToDust = getTotalDirection(mole.facing, mole.tile) + World.queue("await_mole_to_face", 1) { + if (tileToDust == Tile.EMPTY) { + logger.info { "failed to get facing tile for Giant Mole, using default tile." } + tileToDust = initialCaveTile + } + mole.face(tileToDust) + World.queue("display_burrow_dust", 1) { + if (shouldThrowDirt()) { + handleDirtOnScreen(mole.tile) + } + mole.setAnimation("giant_mole_burrow") + areaGraphic("burrow_dust", tileToDust) + World.queue("await_mole_burrowing", 1) { + val newLocation = gianMoleSpawns.random(mole) + commandLocation = newLocation!! + mole.tele(newLocation) + } + } } - mole.attackers.clear() //stop players attacking while mole is burrowing away. N: maybe a for loop getting all players attacking and setting their target to null is better? - mole.setAnimation("giant_mole_burrow") - World.queue("await_mole_burrowing", 2) { - val newLocation = giantMoleLair.random(mole) - commandLocation = newLocation!! - mole.tele(newLocation) +} + +fun getTotalDirection(facing: Direction, moleTile: Tile): Tile { + return when (facing) { + Direction.NORTH -> Tile(moleTile.x, moleTile.y + 1) + Direction.SOUTH -> Tile(moleTile.x, moleTile.y - 1) + Direction.EAST -> Tile(moleTile.x + 1, moleTile.y) + Direction.WEST -> Tile(moleTile.x - 1, moleTile.y) + Direction.NORTH_EAST, Direction.SOUTH_EAST -> Tile(moleTile.x + 1, moleTile.y) + Direction.NORTH_WEST, Direction.SOUTH_WEST -> Tile(moleTile.x - 1, moleTile.y) + Direction.NONE -> Tile.EMPTY } } @@ -143,7 +171,7 @@ fun shouldBurrowAway(health: Int): Boolean { val maxThreshold = maxHealth * 0.50 if (health in minThreshold.toInt()..maxThreshold.toInt()) { val shouldBurrow = Random.nextInt(0, 100) - return shouldBurrow <= 25 + return shouldBurrow <= 50 } return false } From 484260e701feca17a2b2ad96f4cb8f18ebe5b618 Mon Sep 17 00:00:00 2001 From: Syntax Date: Mon, 29 Apr 2024 21:20:23 +0100 Subject: [PATCH 4/9] * Add animation `giant_mole_burrow_up` to `animation.yml` * Remove redundant comment in `npcs.yml` * Add sounds `giant_mole_burrow_down`, `giant_mole_attack`, `giant_mole_hit`, `giant_mole_burrow`, and `giant_mole_death` to `sounds.yml` * Add complete drop table for `Giant mole` in `drops.yml` * Remove redundant commends from `GiantMole.kts` * Add `giant_mole_burrow_down` sound when the `Giant mole` burrow to a new location * Add `mole_burrow_up` when the `Giant mole` has move to it's new location * Add inventory check in a scenario where a player may drop their light source or was extinguished to then remove or apple the darkness overlay --- data/definitions/animations.yml | 3 +- data/definitions/npcs.yml | 2 +- data/definitions/sounds.yml | 7 +- data/spawns/drops.yml | 100 +++++++++++++++++- .../entity/npc/combat/type/GiantMole.kts | 34 +++--- 5 files changed, 124 insertions(+), 22 deletions(-) diff --git a/data/definitions/animations.yml b/data/definitions/animations.yml index 7c255d849d..26575d0f25 100644 --- a/data/definitions/animations.yml +++ b/data/definitions/animations.yml @@ -1673,4 +1673,5 @@ giant_mole_burrow: 3314 giant_mole_attack: 3312 giant_mole_hit: 3311 giant_mole_death: 3310 -dirt_Projectile: 570 \ No newline at end of file +dirt_Projectile: 570 +giant_mole_burrow_up: 1664 \ No newline at end of file diff --git a/data/definitions/npcs.yml b/data/definitions/npcs.yml index c0fd247681..5ff1cc81a0 100644 --- a/data/definitions/npcs.yml +++ b/data/definitions/npcs.yml @@ -1830,7 +1830,7 @@ al_the_camel: large_head: true wander_radius: 4 examine: "A camel who has the soul of a poet." -giant_mole: # this is the wrong ID for giant mole still need to find the correct one | burrow anim id found | coming up from ground not found +giant_mole: id: 3340 hitpoints: 2000 att: 200 diff --git a/data/definitions/sounds.yml b/data/definitions/sounds.yml index b1255d0cdb..26fb4738dd 100644 --- a/data/definitions/sounds.yml +++ b/data/definitions/sounds.yml @@ -194,4 +194,9 @@ knife_throw: 2707 thrown: 2708 godwars_saradomin_magic_impact: 3853 godwars_godsword_special_attack: 3865 -pottery: 2588 \ No newline at end of file +pottery: 2588 +giant_mole_burrow_down: 1641 +giant_mole_attack: 1642 +giant_mole_hit: 1646 +giant_mole_burrow: 1643 +giant_mole_death: 1645 \ No newline at end of file diff --git a/data/spawns/drops.yml b/data/spawns/drops.yml index eec4ca1a1e..f5f243c114 100644 --- a/data/spawns/drops.yml +++ b/data/spawns/drops.yml @@ -890,10 +890,11 @@ human_drop_table: - type: all drops: - id: bones -giant_mole: +giant_mole_drop_table: type: all drops: - - drops: + - type: all + drops: - id: big_bones - id: mole_claw - id: mole_skin @@ -939,6 +940,10 @@ giant_mole: - id: shark amount: 4 chance: 1 + - roll: 34 + drops: + - id: nothing + chance: 1 - roll: 42 drops: - id: mithril_bar @@ -953,6 +958,10 @@ giant_mole: - id: iron_ore_noted amount: 100 chance: 1 + - roll: 77 + drops: + - id: uncut_sapphire + chance: 1 - roll: 128 drops: - id: mithril_battleaxe @@ -960,4 +969,91 @@ giant_mole: - id: rune_med_helm chance: 1 - id: oyster_pearls + chance: 1 + - roll: 154 + drops: + - id: uncut_emerald + chance: 1 + - roll: 189 + drops: + - id: loop_half_of_a_key + chance: 1 + - id: tooth_half_of_a_key + chance: 1 + - roll: 195 + drops: + - id: coins + amount: 3000 + chance: 1 + - roll: 309 + drops: + - id: uncut_ruby + chance: 1 + - roll: 819 + drops: + - id: rune_bar + chance: 1 + - roll: 824 + drops: + - id: nature_talisman + chance: 1 + - roll: 1237 + drops: + - id: uncut_diamond + chance: 1 + - roll: 1365 + drops: + - id: nature_rune + amount: 67 + chance: 1 + - id: rune_2h_sword + chance: 1 + - id: rune_battle_axe + chance: 1 + - roll: 2048 + drops: + - id: law_rune + amount: 45 + chance: 1 + - id: death_rune + amount: 45 + chance: 1 + - id: steel_arrow + amount: 150 + chance: 1 + - id: rune_arrow + amount: 42 + chance: 1 + - id: adamant_javelin + amount: 20 + chance: 1 + - id: rune_sq_shield + chance: 1 + - id: dragonstone + chance: 1 + - id: silver_ore_noted + amount: 100 + chance: 1 + - roll: 2473 + drops: + - id: rune_javelin + amount: 5 + chance: 1 + - roll: 3935 + drops: + - id: rune_spear + chance: 1 + - roll: 4096 + drops: + - id: rune_kiteshield + chance: 1 + - id: dragon_med_helm + chance: 1 + - roll: 7869 + drops: + - id: shield_left_half + chance: 1 + - roll: 10492 + drops: + - id: dragon_spear chance: 1 \ No newline at end of file diff --git a/game/src/main/kotlin/world/gregs/voidps/world/interact/entity/npc/combat/type/GiantMole.kts b/game/src/main/kotlin/world/gregs/voidps/world/interact/entity/npc/combat/type/GiantMole.kts index 0c0f53b498..754452cb5a 100644 --- a/game/src/main/kotlin/world/gregs/voidps/world/interact/entity/npc/combat/type/GiantMole.kts +++ b/game/src/main/kotlin/world/gregs/voidps/world/interact/entity/npc/combat/type/GiantMole.kts @@ -3,7 +3,6 @@ package world.gregs.voidps.world.interact.entity.npc.combat.type import com.github.michaelbull.logging.InlineLogger import world.gregs.voidps.engine.client.ui.close import world.gregs.voidps.engine.client.ui.closeInterfaces -import world.gregs.voidps.engine.client.ui.event.adminCommand import world.gregs.voidps.engine.client.ui.interfaceOption import world.gregs.voidps.engine.client.ui.open import world.gregs.voidps.engine.data.definition.AreaDefinitions @@ -22,6 +21,7 @@ import world.gregs.voidps.engine.entity.obj.objectOperate import world.gregs.voidps.engine.entity.playerSpawn import world.gregs.voidps.engine.inject import world.gregs.voidps.engine.inv.inventory +import world.gregs.voidps.engine.inv.itemChange import world.gregs.voidps.engine.inv.transact.operation.ReplaceItem.replace import world.gregs.voidps.engine.map.collision.random import world.gregs.voidps.type.Direction @@ -30,16 +30,13 @@ import world.gregs.voidps.world.interact.entity.combat.* import world.gregs.voidps.world.interact.entity.combat.hit.combatAttack import world.gregs.voidps.world.interact.entity.gfx.areaGraphic import world.gregs.voidps.world.interact.entity.player.equip.inventoryOption +import world.gregs.voidps.world.interact.entity.sound.areaSound import kotlin.random.Random val logger = InlineLogger() val areas: AreaDefinitions by inject() val players: Players by inject() -//TODO: Add drop table -//TODO: inventory update: if the players light source get's turned off need to reapply darnkess overlay - -// list of tiles where the mole hills are located. val acceptedTiles = listOf( Tile(3005, 3376, 0), Tile(2999, 3375, 0), @@ -51,14 +48,6 @@ val giantMoleLair = areas["giant_mole_lair"] val gianMoleSpawns = areas["giant_mole_spawn_area"] val initialCaveTile: Tile = Tile(1752, 5237, 0) -//temp -var commandLocation: Tile = Tile.EMPTY - -adminCommand("tomole") { - player.tele(commandLocation) -} -//temp - inventoryOption("Dig") { val playerTile: Tile = player.tile if(!acceptedTiles.contains(playerTile)) { @@ -111,11 +100,12 @@ fun giantMoleBurrow(mole: NPC) { handleDirtOnScreen(mole.tile) } mole.setAnimation("giant_mole_burrow") + areaSound("giant_mole_burrow_down", mole.tile) areaGraphic("burrow_dust", tileToDust) World.queue("await_mole_burrowing", 1) { val newLocation = gianMoleSpawns.random(mole) - commandLocation = newLocation!! - mole.tele(newLocation) + mole.tele(newLocation!!) + mole.setAnimation("mole_burrow_up") } } } @@ -171,7 +161,7 @@ fun shouldBurrowAway(health: Int): Boolean { val maxThreshold = maxHealth * 0.50 if (health in minThreshold.toInt()..maxThreshold.toInt()) { val shouldBurrow = Random.nextInt(0, 100) - return shouldBurrow <= 50 + return shouldBurrow <= 25 } return false } @@ -196,7 +186,17 @@ playerSpawn { player -> } } -// check player inventory to see if they have a lit light source. +itemChange("inventory") { player: Player -> + if (giantMoleLair.contains(player.tile)) { + val hasLightSource = hasLightSource(player) + if (!hasLightSource && !player.interfaces.contains("level_three_darkness")) { + player.open("level_three_darkness") + } else if (hasLightSource && player.interfaces.contains("level_three_darkness")) { + player.close("level_three_darkness") + } + } +} + fun hasLightSource(player: Player): Boolean { val playerItems = player.inventory.items From 89cc38f1f4e61edfee80f2a4072e50cd453e0673 Mon Sep 17 00:00:00 2001 From: Syntax Date: Tue, 30 Apr 2024 00:12:44 +0100 Subject: [PATCH 5/9] * Fix capitalization error in `animation.yml` * Add `Baby Mole` spawns to `npcs-spawns.ym` * Add `Baby Mole` to `npcs.yml` * Change world timer checking to an NPC Clock * Fix incorrect implementation of clearing current attacks on giant mole --- data/definitions/animations.yml | 2 +- data/definitions/npcs.yml | 8 +++- data/spawns/npc-spawns.yml | 30 ++++++++++++ .../entity/npc/combat/type/GiantMole.kts | 46 ++++++++++--------- 4 files changed, 61 insertions(+), 25 deletions(-) diff --git a/data/definitions/animations.yml b/data/definitions/animations.yml index 26575d0f25..d7cb670676 100644 --- a/data/definitions/animations.yml +++ b/data/definitions/animations.yml @@ -1673,5 +1673,5 @@ giant_mole_burrow: 3314 giant_mole_attack: 3312 giant_mole_hit: 3311 giant_mole_death: 3310 -dirt_Projectile: 570 +dirt_projectile: 570 giant_mole_burrow_up: 1664 \ No newline at end of file diff --git a/data/definitions/npcs.yml b/data/definitions/npcs.yml index 5ff1cc81a0..ab890ae1b5 100644 --- a/data/definitions/npcs.yml +++ b/data/definitions/npcs.yml @@ -1840,5 +1840,9 @@ giant_mole: style: crush race: giant_mole respawn_delay: 16 - wander_radius: 5 - examine: "Holy Mole-y!" \ No newline at end of file + wander_radius: 8 + examine: "Holy Mole-y!" +baby_mole: + id: 3341 + wander_radius: 6 + examine: "I will call him, Mini Mole." diff --git a/data/spawns/npc-spawns.yml b/data/spawns/npc-spawns.yml index 31e7afdc12..2dc6d7ddb1 100644 --- a/data/spawns/npc-spawns.yml +++ b/data/spawns/npc-spawns.yml @@ -2,6 +2,36 @@ - { id: banker_fist_of_guthix, x: 1705, y: 5599 } # 6993 - { id: giant_mole, x: 1762, y: 5185 } +- { id: baby_mole, x: 1763, y: 5163 } +- { id: baby_mole, x: 1760, y: 5167 } +- { id: baby_mole, x: 1759, y: 5161 } +- { id: baby_mole, x: 1764, y: 5184 } +- { id: baby_mole, x: 1759, y: 5193 } +- { id: baby_mole, x: 1758, y: 5184 } +- { id: baby_mole, x: 1756, y: 5179 } +- { id: baby_mole, x: 1741, y: 5186 } +- { id: baby_mole, x: 1754, y: 5197 } +- { id: baby_mole, x: 1761, y: 5197 } +- { id: baby_mole, x: 1774, y: 5204 } +- { id: baby_mole, x: 1782, y: 5217 } +- { id: baby_mole, x: 1781, y: 5232 } +- { id: baby_mole, x: 1771, y: 5220 } +- { id: baby_mole, x: 1763, y: 5215 } +- { id: baby_mole, x: 1756, y: 5221 } +- { id: baby_mole, x: 1741, y: 5220 } +- { id: baby_mole, x: 1738, y: 5209 } +- { id: baby_mole, x: 1744, y: 5205 } +- { id: baby_mole, x: 1751, y: 5207 } +- { id: baby_mole, x: 1755, y: 5199 } +- { id: baby_mole, x: 1774, y: 5174 } +- { id: baby_mole, x: 1777, y: 5188 } +- { id: baby_mole, x: 1775, y: 5194 } +- { id: baby_mole, x: 1775, y: 5166 } +- { id: baby_mole, x: 1762, y: 5151 } +- { id: baby_mole, x: 1778, y: 5149 } +- { id: baby_mole, x: 1744, y: 5151 } +- { id: baby_mole, x: 1737, y: 5157 } +- { id: baby_mole, x: 1748, y: 5168 } # 7243 - { id: rat, x: 1816, y: 4836, level: 1, members: true } - { id: rat, x: 1815, y: 4832, members: true } diff --git a/game/src/main/kotlin/world/gregs/voidps/world/interact/entity/npc/combat/type/GiantMole.kts b/game/src/main/kotlin/world/gregs/voidps/world/interact/entity/npc/combat/type/GiantMole.kts index 754452cb5a..5de51d2fe8 100644 --- a/game/src/main/kotlin/world/gregs/voidps/world/interact/entity/npc/combat/type/GiantMole.kts +++ b/game/src/main/kotlin/world/gregs/voidps/world/interact/entity/npc/combat/type/GiantMole.kts @@ -5,10 +5,13 @@ import world.gregs.voidps.engine.client.ui.close import world.gregs.voidps.engine.client.ui.closeInterfaces import world.gregs.voidps.engine.client.ui.interfaceOption import world.gregs.voidps.engine.client.ui.open +import world.gregs.voidps.engine.client.variable.hasClock +import world.gregs.voidps.engine.client.variable.start import world.gregs.voidps.engine.data.definition.AreaDefinitions import world.gregs.voidps.engine.entity.World import world.gregs.voidps.engine.entity.character.face import world.gregs.voidps.engine.entity.character.facing +import world.gregs.voidps.engine.entity.character.mode.EmptyMode import world.gregs.voidps.engine.entity.character.mode.move.enterArea import world.gregs.voidps.engine.entity.character.mode.move.exitArea import world.gregs.voidps.engine.entity.character.move.tele @@ -27,7 +30,7 @@ import world.gregs.voidps.engine.map.collision.random import world.gregs.voidps.type.Direction import world.gregs.voidps.type.Tile import world.gregs.voidps.world.interact.entity.combat.* -import world.gregs.voidps.world.interact.entity.combat.hit.combatAttack +import world.gregs.voidps.world.interact.entity.combat.hit.npcCombatHit import world.gregs.voidps.world.interact.entity.gfx.areaGraphic import world.gregs.voidps.world.interact.entity.player.equip.inventoryOption import world.gregs.voidps.world.interact.entity.sound.areaSound @@ -70,24 +73,24 @@ interfaceOption(component = "stayout", id = "warning_dark") { player.closeInterfaces() } -combatAttack { - val npc = target as NPC - if(npc.id == "giant_mole") { - val currentHealth = npc.levels.get(Skill.Constitution) - var shouldBurrow = false - if (it.fightStyle == "magic" && damage != 0) { - shouldBurrow = shouldBurrowAway(currentHealth) - } else if (it.fightStyle != "magic") { - shouldBurrow = shouldBurrowAway(currentHealth) - } - if(shouldBurrow && !World.timers.contains("await_mole_burrowing")) { - giantMoleBurrow(npc) - } +npcCombatHit("giant_mole") { + val currentHealth = it.levels.get(Skill.Constitution) + var shouldBurrow = false + if (it.fightStyle == "magic" && damage != 0) { + shouldBurrow = shouldBurrowAway(currentHealth) + } else if (it.fightStyle != "magic") { + shouldBurrow = shouldBurrowAway(currentHealth) + } + if (shouldBurrow && !it.hasClock("awaiting_mole_burrow_complete")) { + it.start("awaiting_mole_burrow_complete", 4) + giantMoleBurrow(it) } } fun giantMoleBurrow(mole: NPC) { - mole.attackers.clear() + for (attacker in mole.attackers) { + attacker.mode = EmptyMode + } var tileToDust = getTotalDirection(mole.facing, mole.tile) World.queue("await_mole_to_face", 1) { if (tileToDust == Tile.EMPTY) { @@ -138,12 +141,11 @@ fun handleDirtOnScreen(moleTile: Tile) { } for (player in nearMole) { player.open("dirt_on_screen") - val playerInventory = player.inventory.items - for (item in playerInventory) { - if (item.id.contains("candle_lit")) { - val newItem = item.id.replace("_lit", "") - player.inventory.transaction { - replace(item.id, newItem) + player.inventory.transaction { + for (index in inventory.indices) { + val item = inventory[index] + if (item.id.endsWith("candle_lit")) { + replace(item.id, item.id.removeSuffix("_lit")) } } } @@ -201,7 +203,7 @@ fun hasLightSource(player: Player): Boolean { val playerItems = player.inventory.items for (item in playerItems) { - if (item.id.contains("lantern_lit") || item.id.contains("candle_lit")) { + if (item.id.endsWith("lantern_lit") || item.id.endsWith("candle_lit")) { return true } } From 9a1e483021c24064228970e2a4117c40c456281c Mon Sep 17 00:00:00 2001 From: Syntax <79747812+Zag-bop@users.noreply.github.com> Date: Tue, 30 Apr 2024 18:06:47 +0100 Subject: [PATCH 6/9] * Add mole `attackers clear` when stopping players attacking the mole --- .../voidps/world/interact/entity/npc/combat/type/GiantMole.kts | 1 + 1 file changed, 1 insertion(+) diff --git a/game/src/main/kotlin/world/gregs/voidps/world/interact/entity/npc/combat/type/GiantMole.kts b/game/src/main/kotlin/world/gregs/voidps/world/interact/entity/npc/combat/type/GiantMole.kts index 5de51d2fe8..510f1f8c47 100644 --- a/game/src/main/kotlin/world/gregs/voidps/world/interact/entity/npc/combat/type/GiantMole.kts +++ b/game/src/main/kotlin/world/gregs/voidps/world/interact/entity/npc/combat/type/GiantMole.kts @@ -91,6 +91,7 @@ fun giantMoleBurrow(mole: NPC) { for (attacker in mole.attackers) { attacker.mode = EmptyMode } + mole.attackers.clear() var tileToDust = getTotalDirection(mole.facing, mole.tile) World.queue("await_mole_to_face", 1) { if (tileToDust == Tile.EMPTY) { From 86e9cce70b8c869dded003657a87b23bd90ce548 Mon Sep 17 00:00:00 2001 From: Syntax <79747812+Zag-bop@users.noreply.github.com> Date: Tue, 30 Apr 2024 18:46:34 +0100 Subject: [PATCH 7/9] * Change `inventoryOption` to include the item that is being used. * Change `World.queue` to `mole.queue` --- .../interact/entity/npc/combat/type/GiantMole.kts | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/game/src/main/kotlin/world/gregs/voidps/world/interact/entity/npc/combat/type/GiantMole.kts b/game/src/main/kotlin/world/gregs/voidps/world/interact/entity/npc/combat/type/GiantMole.kts index 510f1f8c47..967c56e5c2 100644 --- a/game/src/main/kotlin/world/gregs/voidps/world/interact/entity/npc/combat/type/GiantMole.kts +++ b/game/src/main/kotlin/world/gregs/voidps/world/interact/entity/npc/combat/type/GiantMole.kts @@ -27,6 +27,7 @@ import world.gregs.voidps.engine.inv.inventory import world.gregs.voidps.engine.inv.itemChange import world.gregs.voidps.engine.inv.transact.operation.ReplaceItem.replace import world.gregs.voidps.engine.map.collision.random +import world.gregs.voidps.engine.queue.queue import world.gregs.voidps.type.Direction import world.gregs.voidps.type.Tile import world.gregs.voidps.world.interact.entity.combat.* @@ -51,12 +52,12 @@ val giantMoleLair = areas["giant_mole_lair"] val gianMoleSpawns = areas["giant_mole_spawn_area"] val initialCaveTile: Tile = Tile(1752, 5237, 0) -inventoryOption("Dig") { +inventoryOption("Dig", "Spade") { val playerTile: Tile = player.tile + player.setAnimation("dig_with_spade") if(!acceptedTiles.contains(playerTile)) { return@inventoryOption } - player.setAnimation("dig_with_spade") player.open("warning_dark") } @@ -93,20 +94,20 @@ fun giantMoleBurrow(mole: NPC) { } mole.attackers.clear() var tileToDust = getTotalDirection(mole.facing, mole.tile) - World.queue("await_mole_to_face", 1) { + mole.queue("await_mole_to_face", 1) { if (tileToDust == Tile.EMPTY) { logger.info { "failed to get facing tile for Giant Mole, using default tile." } tileToDust = initialCaveTile } mole.face(tileToDust) - World.queue("display_burrow_dust", 1) { + mole.queue("display_burrow_dust", 1) { if (shouldThrowDirt()) { handleDirtOnScreen(mole.tile) } mole.setAnimation("giant_mole_burrow") areaSound("giant_mole_burrow_down", mole.tile) areaGraphic("burrow_dust", tileToDust) - World.queue("await_mole_burrowing", 1) { + mole.queue("await_mole_burrowing", 1) { val newLocation = gianMoleSpawns.random(mole) mole.tele(newLocation!!) mole.setAnimation("mole_burrow_up") From 6434112bc6669dcf78804a632ce69218e8213b59 Mon Sep 17 00:00:00 2001 From: Syntax <79747812+Zag-bop@users.noreply.github.com> Date: Tue, 30 Apr 2024 23:55:33 +0100 Subject: [PATCH 8/9] * Change the directional choices for the mole to include northeast, northwest, southeast, and southwest options instead of just north, east, south, and west * Add directional choices to be random --- .../entity/npc/combat/type/GiantMole.kts | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/game/src/main/kotlin/world/gregs/voidps/world/interact/entity/npc/combat/type/GiantMole.kts b/game/src/main/kotlin/world/gregs/voidps/world/interact/entity/npc/combat/type/GiantMole.kts index 967c56e5c2..be6548be0e 100644 --- a/game/src/main/kotlin/world/gregs/voidps/world/interact/entity/npc/combat/type/GiantMole.kts +++ b/game/src/main/kotlin/world/gregs/voidps/world/interact/entity/npc/combat/type/GiantMole.kts @@ -93,7 +93,7 @@ fun giantMoleBurrow(mole: NPC) { attacker.mode = EmptyMode } mole.attackers.clear() - var tileToDust = getTotalDirection(mole.facing, mole.tile) + var tileToDust = mole.tile.add(getRandomFacing(mole.facing).delta) mole.queue("await_mole_to_face", 1) { if (tileToDust == Tile.EMPTY) { logger.info { "failed to get facing tile for Giant Mole, using default tile." } @@ -116,18 +116,15 @@ fun giantMoleBurrow(mole: NPC) { } } -fun getTotalDirection(facing: Direction, moleTile: Tile): Tile { - return when (facing) { - Direction.NORTH -> Tile(moleTile.x, moleTile.y + 1) - Direction.SOUTH -> Tile(moleTile.x, moleTile.y - 1) - Direction.EAST -> Tile(moleTile.x + 1, moleTile.y) - Direction.WEST -> Tile(moleTile.x - 1, moleTile.y) - Direction.NORTH_EAST, Direction.SOUTH_EAST -> Tile(moleTile.x + 1, moleTile.y) - Direction.NORTH_WEST, Direction.SOUTH_WEST -> Tile(moleTile.x - 1, moleTile.y) - Direction.NONE -> Tile.EMPTY - } +fun getRandomFacing(currentlyFacing: Direction): Direction { + var randomDirection: Direction + do { + randomDirection = Direction.entries.filter { it != Direction.NONE }.random() + } while (randomDirection == currentlyFacing) + return randomDirection } + // 13% chance to throw dirt on players screen fun shouldThrowDirt(): Boolean { val dirtChance = Random.nextInt(0, 100) From c8a2fe7058b3cc4de38873d7aeae23a61322ec17 Mon Sep 17 00:00:00 2001 From: GregHib Date: Wed, 1 May 2024 19:23:25 +0100 Subject: [PATCH 9/9] Fix spade --- .../entity/npc/combat/type/GiantMole.kts | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/game/src/main/kotlin/world/gregs/voidps/world/interact/entity/npc/combat/type/GiantMole.kts b/game/src/main/kotlin/world/gregs/voidps/world/interact/entity/npc/combat/type/GiantMole.kts index be6548be0e..fcf1c701df 100644 --- a/game/src/main/kotlin/world/gregs/voidps/world/interact/entity/npc/combat/type/GiantMole.kts +++ b/game/src/main/kotlin/world/gregs/voidps/world/interact/entity/npc/combat/type/GiantMole.kts @@ -30,10 +30,11 @@ import world.gregs.voidps.engine.map.collision.random import world.gregs.voidps.engine.queue.queue import world.gregs.voidps.type.Direction import world.gregs.voidps.type.Tile -import world.gregs.voidps.world.interact.entity.combat.* +import world.gregs.voidps.world.interact.entity.combat.attackers +import world.gregs.voidps.world.interact.entity.combat.fightStyle import world.gregs.voidps.world.interact.entity.combat.hit.npcCombatHit import world.gregs.voidps.world.interact.entity.gfx.areaGraphic -import world.gregs.voidps.world.interact.entity.player.equip.inventoryOption +import world.gregs.voidps.world.interact.entity.player.equip.inventoryItem import world.gregs.voidps.world.interact.entity.sound.areaSound import kotlin.random.Random @@ -52,11 +53,11 @@ val giantMoleLair = areas["giant_mole_lair"] val gianMoleSpawns = areas["giant_mole_spawn_area"] val initialCaveTile: Tile = Tile(1752, 5237, 0) -inventoryOption("Dig", "Spade") { +inventoryItem("Dig", "spade") { val playerTile: Tile = player.tile player.setAnimation("dig_with_spade") - if(!acceptedTiles.contains(playerTile)) { - return@inventoryOption + if (!acceptedTiles.contains(playerTile)) { + return@inventoryItem } player.open("warning_dark") } @@ -168,20 +169,20 @@ fun shouldBurrowAway(health: Int): Boolean { } enterArea("giant_mole_lair") { - if(!hasLightSource(player)) { + if (!hasLightSource(player)) { player.open("level_three_darkness") } } exitArea("giant_mole_lair") { - if(player.interfaces.contains("level_three_darkness")) { + if (player.interfaces.contains("level_three_darkness")) { player.close("level_three_darkness") } } playerSpawn { player -> - if(giantMoleLair.contains(player.tile)) { - if(!hasLightSource(player)) { + if (giantMoleLair.contains(player.tile)) { + if (!hasLightSource(player)) { player.open("level_three_darkness") } }