diff --git a/data/definitions/animations.yml b/data/definitions/animations.yml index f6df0280a..bfb6d700e 100644 --- a/data/definitions/animations.yml +++ b/data/definitions/animations.yml @@ -1801,3 +1801,10 @@ gudrun_hugging: 14733 restless_ghost_ascends: 4018 restless_ghost_awakens: 4019 restless_ghost_warlock_spawn: 1552 +climb_through_pipe: 10580 +gnome_wall_run: 2922 +gnome_run_up: 11784 +gnome_jump: 11785 +gnome_swing: 11789 +gnome_jump_barrier: 2923 +gnome_pipe_land: 2924 diff --git a/data/definitions/npcs.yml b/data/definitions/npcs.yml index 803d4f26d..9a7a95bbf 100644 --- a/data/definitions/npcs.yml +++ b/data/definitions/npcs.yml @@ -2347,3 +2347,9 @@ suit_of_armour: weapon_style: sword race: human examine: "A dusty old suit of armour." +gnome_trainer: + id: 162 + race: gnome + large_head: true + wander_radius: 4 + examine: "He can advise on training." diff --git a/data/definitions/objects.yml b/data/definitions/objects.yml index 7365234dc..027fa238d 100644 --- a/data/definitions/objects.yml +++ b/data/definitions/objects.yml @@ -11888,4 +11888,43 @@ coffin_restless_ghost_2: examine: "Ooooh! Spooky!" railing_wizards_tower: id: 37668 - examine: "A sturdy metal railing." \ No newline at end of file + examine: "A sturdy metal railing." +gnome_log_balance: + id: 2295 + examine: "A slippery log I can walk across." +gnome_obstacle_net: + id: 2285 + examine: "This must be climbed over." +gnome_tree_branch_up: + id: 35970 + examine: "I can climb up this." +gnome_tree_branch_down: + id: 2314 + examine: "I can climb down this." +gnome_balancing_rope: + id: 2312 + examine: "I can balance on this rope." +gnome_balancing_rope_end: + id: 4059 + examine: "I can balance on this rope." +gnome_obstacle_net_free_standing: + id: 2286 + examine: "This must be climbed over." +gnome_obstacle_pipe_east: + id: 43543 + examine: "A pipe I can squeeze through." +gnome_obstacle_pipe_west: + id: 43544 + examine: "A pipe I can squeeze through." +gnome_tree_branch_advanced: + id: 43528 + examine: "I can climb up this." +gnome_sign_post_advanced: + id: 43581 + examine: "It doesn't look finished, but the material is tough enough to grip hold of." +gnome_pole_advanced: + id: 43529 + examine: "A long metal pole." +gnome_barrier_advanced: + id: 43539 + examine: "It might be possible to vault over it." diff --git a/data/definitions/render-emotes.yml b/data/definitions/render-emotes.yml index 1715a8163..0c518f439 100644 --- a/data/definitions/render-emotes.yml +++ b/data/definitions/render-emotes.yml @@ -1,2 +1,3 @@ human_stand: 1426 -dororan_stand: 1880 \ No newline at end of file +dororan_stand: 1880 +rope_balance: 155 diff --git a/data/definitions/variables-custom.yml b/data/definitions/variables-custom.yml index 77a67f4a8..8c1b94066 100644 --- a/data/definitions/variables-custom.yml +++ b/data/definitions/variables-custom.yml @@ -475,5 +475,17 @@ equip_crossbow: persist: true format: boolean flagstaff_runefest: + persist: true + format: boolean +gnome_course_stage: + persist: true + format: int +gnome_course_laps: + persist: true + format: int +gnome_course_advanced_laps: + persist: true + format: int +gnome_course_reward_claimed: persist: true format: boolean \ No newline at end of file diff --git a/data/spawns/npc-spawns.yml b/data/spawns/npc-spawns.yml index 460d0414c..9932c0c3d 100644 --- a/data/spawns/npc-spawns.yml +++ b/data/spawns/npc-spawns.yml @@ -576,6 +576,18 @@ - { id: butterfly_1, x: 2437, y: 3425, members: true } - { id: butterfly_1, x: 2438, y: 3422, members: true } - { id: butterfly_1, x: 2450, y: 3419, members: true } +- { id: gnome_trainer, x: 2469, y: 3423, members: true } +- { id: gnome_trainer, x: 2469, y: 3434, members: true } +- { id: gnome_trainer, x: 2470, y: 3426, members: true } +- { id: gnome_trainer, x: 2477, y: 3426, members: true } +- { id: gnome_trainer, x: 2479, y: 3427, members: true } +- { id: gnome_trainer, x: 2482, y: 3422, members: true } +- { id: gnome_trainer, x: 2489, y: 3423, members: true } +- { id: gnome_trainer, x: 2489, y: 3427, members: true } +- { id: gnome_trainer, x: 2490, y: 3435, members: true } +- { id: gnome_trainer, x: 2475, y: 3422, level: 1, members: true } +- { id: gnome_trainer, x: 2475, y: 3421, level: 2, members: true } +- { id: gnome_trainer, x: 2474, y: 3419, level: 3, members: true } # 9782 - { id: butterfly_5, x: 2448, y: 3469, members: true } - { id: butterfly_5, x: 2447, y: 3467, members: true } diff --git a/engine/src/main/kotlin/world/gregs/voidps/engine/entity/character/mode/move/target/TargetStrategy.kt b/engine/src/main/kotlin/world/gregs/voidps/engine/entity/character/mode/move/target/TargetStrategy.kt index 38107d75f..cc22d172e 100644 --- a/engine/src/main/kotlin/world/gregs/voidps/engine/entity/character/mode/move/target/TargetStrategy.kt +++ b/engine/src/main/kotlin/world/gregs/voidps/engine/entity/character/mode/move/target/TargetStrategy.kt @@ -46,6 +46,7 @@ interface TargetStrategy { is Tile -> TileTargetStrategy(entity) is GameObject -> when (entity.id) { "archery_target" -> TileTargetStrategy(entity.tile.addX(5)) + "gnome_obstacle_pipe_east", "gnome_obstacle_pipe_west" -> TileTargetStrategy(entity.tile.addY(-1)) "lumbridge_church_bell" -> TileTargetStrategy(entity.tile.addY(-1)) else -> ObjectTargetStrategy(entity) } diff --git a/engine/src/main/kotlin/world/gregs/voidps/engine/entity/character/player/PlayerVisuals.kt b/engine/src/main/kotlin/world/gregs/voidps/engine/entity/character/player/PlayerVisuals.kt index 9905674d5..fe02dc4c2 100644 --- a/engine/src/main/kotlin/world/gregs/voidps/engine/entity/character/player/PlayerVisuals.kt +++ b/engine/src/main/kotlin/world/gregs/voidps/engine/entity/character/player/PlayerVisuals.kt @@ -58,12 +58,16 @@ var Player.headIcon: Int headIcon = value } -var Player.emote: String +var Player.renderEmote: String get() = get().get(appearance.emote).stringId set(value) = flag { - appearance.emote = get().get(value).id + emote = get().get(value).id } +fun Player.clearRenderEmote() = flag { + emote = 1426 +} + var Player.name: String get() = this["display_name", accountName] set(value) = flag { diff --git a/game/src/main/kotlin/world/gregs/voidps/world/activity/skill/agility/course/GnomeAdvanced.kts b/game/src/main/kotlin/world/gregs/voidps/world/activity/skill/agility/course/GnomeAdvanced.kts new file mode 100644 index 000000000..b9f935db1 --- /dev/null +++ b/game/src/main/kotlin/world/gregs/voidps/world/activity/skill/agility/course/GnomeAdvanced.kts @@ -0,0 +1,106 @@ +package world.gregs.voidps.world.activity.skill.agility.course + +import world.gregs.voidps.engine.client.message +import world.gregs.voidps.engine.client.variable.start +import world.gregs.voidps.engine.entity.character.clearAnimation +import world.gregs.voidps.engine.entity.character.exactMove +import world.gregs.voidps.engine.entity.character.face +import world.gregs.voidps.engine.entity.character.move.tele +import world.gregs.voidps.engine.entity.character.npc.NPCs +import world.gregs.voidps.engine.entity.character.player.chat.ChatType +import world.gregs.voidps.engine.entity.character.player.skill.Skill +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.setAnimation +import world.gregs.voidps.engine.entity.obj.objectApproach +import world.gregs.voidps.engine.entity.obj.objectOperate +import world.gregs.voidps.engine.inject +import world.gregs.voidps.engine.queue.strongQueue +import world.gregs.voidps.engine.suspend.approachRange +import world.gregs.voidps.engine.suspend.delay +import world.gregs.voidps.engine.suspend.pause +import world.gregs.voidps.type.Direction +import world.gregs.voidps.type.Tile +import world.gregs.voidps.type.Zone + +val npcs: NPCs by inject() + +objectOperate("Climb-up", "gnome_tree_branch_advanced") { + if (!player.has(Skill.Agility, 85)) { + return@objectOperate + } + npcs.gnomeTrainer("Terrorbirds could climb faster than that!", Zone(9263413)) + player.message("You climb the tree...", ChatType.Filter) + player.setAnimation("climb_up") + player.start("input_delay", 2) + player.strongQueue("branch", 2) { + player.message("... to an even higher platform.", ChatType.Filter) + player.gnomeStage(4) + player.tele(player.tile.add(y = -1, level = 1)) + player.exp(Skill.Agility, 25.0) + } +} + +objectApproach("Run-across", "gnome_sign_post_advanced") { + npcs.gnomeTrainer("Come on! I'd be over there by now.", Zone(13457717)) + player.approachRange(1) + // Pausing for 2 ticks to ensure we're in the correct spot. + // arriveDelay() wouldn't work as objectApproach is called before Movement.tick where "last_movement" is set + pause(2) + player.face(Direction.EAST) + player.setAnimation("gnome_wall_run") + player.start("input_delay", 4) + player.strongQueue("wall-run", 1) { + player.exactMove(Tile(2484, 3418, 3), 60, Direction.EAST) + pause(2) + player.gnomeStage(5) + player.exp(Skill.Agility, 25.0) + player.clearAnimation() + } +} + +objectApproach("Swing-to", "gnome_pole_advanced") { + var tile = player.tile + if (player.tile.x == 2484) { + tile = Tile(2485, 3418, 3) + } + player.steps.clear() + player.face(Direction.NORTH) + player.start("input_delay", 14) + player.strongQueue("run-up", 1) { + onCancel = { + player.tele(Tile(2486, 3418, 3)) + } + player.setAnimation("gnome_run_up") + player.exactMove(tile.copy(y = 3421), 60, Direction.NORTH) + pause(2) + player.setAnimation("gnome_jump") + player.exactMove(tile.copy(y = 3425), 30, Direction.NORTH) + pause(1) + player.setAnimation("gnome_swing") + pause(4) + player.exactMove(tile.copy(y = 3429), 30, Direction.NORTH) + pause(5) + player.exactMove(tile.copy(y = 3432), 30, Direction.NORTH) + delay(2) + player.gnomeStage(6) + player.exp(Skill.Agility, 25.0) + } +} + +objectOperate("Jump-over", "gnome_barrier_advanced") { + player.setAnimation("gnome_jump_barrier") + player.start("input_delay", 4) + player.strongQueue("branch", 1) { + player.exactMove(Tile(2485, 3434, 3), 30, Direction.NORTH) + pause(2) + player.tele(2485, 3436, 0) + player.setAnimation("gnome_pipe_land") + if (player.gnomeStage == 6) { + player.gnomeStage = 0 + player.inc("gnome_course_advanced_laps") + player.exp(Skill.Agility, 605.0) + } + player.exp(Skill.Agility, 25.0) + } +} \ No newline at end of file diff --git a/game/src/main/kotlin/world/gregs/voidps/world/activity/skill/agility/course/GnomeAgility.kt b/game/src/main/kotlin/world/gregs/voidps/world/activity/skill/agility/course/GnomeAgility.kt new file mode 100644 index 000000000..f08ac57ef --- /dev/null +++ b/game/src/main/kotlin/world/gregs/voidps/world/activity/skill/agility/course/GnomeAgility.kt @@ -0,0 +1,32 @@ +package world.gregs.voidps.world.activity.skill.agility.course + +import world.gregs.voidps.engine.entity.character.forceChat +import world.gregs.voidps.engine.entity.character.npc.NPCs +import world.gregs.voidps.engine.entity.character.player.Player +import world.gregs.voidps.type.Zone +import world.gregs.voidps.type.random + +internal fun Player.gnomeStage(stage: Int) { + if (stage == gnomeStage + 1) { + gnomeStage = stage + } +} + +internal var Player.gnomeStage: Int + get() = this["gnome_course_stage", 0] + set(value) { + this["gnome_course_stage"] = value + } + +internal fun NPCs.gnomeTrainer(message: String, zone: Zone) { + val trainer = get(zone).randomOrNull(random) ?: return + trainer.forceChat = message +} + +internal fun NPCs.gnomeTrainer(message: String, zones: List) { + for (zone in zones) { + val trainer = get(zone).randomOrNull(random) ?: continue + trainer.forceChat = message + break + } +} \ No newline at end of file diff --git a/game/src/main/kotlin/world/gregs/voidps/world/activity/skill/agility/course/GnomeStronghold.kts b/game/src/main/kotlin/world/gregs/voidps/world/activity/skill/agility/course/GnomeStronghold.kts new file mode 100644 index 000000000..52eee92a5 --- /dev/null +++ b/game/src/main/kotlin/world/gregs/voidps/world/activity/skill/agility/course/GnomeStronghold.kts @@ -0,0 +1,139 @@ +package world.gregs.voidps.world.activity.skill.agility.course + +import world.gregs.voidps.engine.client.message +import world.gregs.voidps.engine.client.variable.start +import world.gregs.voidps.engine.entity.character.exactMove +import world.gregs.voidps.engine.entity.character.face +import world.gregs.voidps.engine.entity.character.move.tele +import world.gregs.voidps.engine.entity.character.move.walkTo +import world.gregs.voidps.engine.entity.character.npc.NPCs +import world.gregs.voidps.engine.entity.character.player.chat.ChatType +import world.gregs.voidps.engine.entity.character.player.clearRenderEmote +import world.gregs.voidps.engine.entity.character.player.renderEmote +import world.gregs.voidps.engine.entity.character.player.skill.Skill +import world.gregs.voidps.engine.entity.character.player.skill.exp.exp +import world.gregs.voidps.engine.entity.character.setAnimation +import world.gregs.voidps.engine.entity.obj.objectOperate +import world.gregs.voidps.engine.inject +import world.gregs.voidps.engine.queue.strongQueue +import world.gregs.voidps.type.Direction +import world.gregs.voidps.type.Tile +import world.gregs.voidps.type.Zone + +val npcs: NPCs by inject() + +objectOperate("Walk-across", "gnome_log_balance") { + player.start("input_delay", 8) + player.strongQueue("log-balance") { + onCancel = { + player.tele(2474, 3436) + } + npcs.gnomeTrainer("Okay get over that log, quick quick!", listOf(Zone(878901), Zone(878900), Zone(876852))) + player.renderEmote = "rope_balance" + player.walkTo(Tile(2474, 3429), noCollision = true, noRun = true) + player.message("You walk carefully across the slippery log...", ChatType.Filter) + pause(8) + player.clearRenderEmote() + player.gnomeStage(1) + player.exp(Skill.Agility, 7.5) + player.message("... and make it safely to the other side.", ChatType.Filter) + } +} + +objectOperate("Climb-over", "gnome_obstacle_net") { + npcs.gnomeTrainer("Move it, move it, move it!", listOf(Zone(8768252), Zone(876853))) + player.message("You climb the netting...", ChatType.Filter) + player.setAnimation("climb_up") + player.start("input_delay", 2) + player.strongQueue("netting", 2) { + player.gnomeStage(2) + player.tele(player.tile.add(y = -2, level = 1)) + player.exp(Skill.Agility, 7.5) + } +} + +objectOperate("Climb", "gnome_tree_branch_up") { + npcs.gnomeTrainer("That's it - straight up", listOf(Zone(5069109), Zone(5071157))) + player.message("You climb the tree...", ChatType.Filter) + player.setAnimation("climb_up") + player.start("input_delay", 2) + player.strongQueue("branch", 2) { + player.message("... to the platform above.", ChatType.Filter) + player.gnomeStage(3) + player.tele(2473, 3420, 2) + player.exp(Skill.Agility, 5.0) + } +} + +objectOperate("Walk-on", "gnome_balancing_rope") { + npcs.gnomeTrainer("Come on scaredy cat, get across that rope!", Zone(9263413)) + player.walkTo(Tile(2483, 3420, 2), noCollision = true, noRun = true) + player.start("input_delay", 7) + player.renderEmote = "rope_balance" + player.strongQueue("rope-balance", 7) { + player.gnomeStage(4) + player.clearRenderEmote() + player.exp(Skill.Agility, 7.5) + player.message("You passed the obstacle successfully.", ChatType.Filter) + } +} + +objectOperate("Walk-on", "gnome_balancing_rope_end") { + player.walkTo(Tile(2477, 3420, 2), noCollision = true, noRun = true) + player.start("input_delay", 7) + player.renderEmote = "rope_balance" + player.strongQueue("rope-balance", 7) { + player.clearRenderEmote() + player.exp(Skill.Agility, 7.5) + player.message("You passed the obstacle successfully.", ChatType.Filter) + } +} + +objectOperate("Climb-down", "gnome_tree_branch_down") { + player.message("You climb the tree...", ChatType.Filter) + player.setAnimation("climb_down") + player.start("input_delay", 2) + player.strongQueue("branch", 2) { + player.gnomeStage(5) + player.tele(2486, 3420, 0) + player.exp(Skill.Agility, 5.0) + } +} + +objectOperate("Climb-over", "gnome_obstacle_net_free_standing") { + npcs.gnomeTrainer("My Granny can move faster than you.", Zone(876854)) + player.message("You climb the netting.", ChatType.Filter) + player.setAnimation("climb_up") + player.start("input_delay", 2) + player.strongQueue("netting", 2) { + player.gnomeStage(6) + player.tele(player.tile.add(y = 2)) + player.exp(Skill.Agility, 7.5) + } +} + +objectOperate("Squeeze-through", "gnome_obstacle_pipe_*") { + player.strongQueue("obstacle_pipe", 1) { + onCancel = { + player.tele(target.tile.addY(-1)) + } + player.start("input_delay", 8) + player.face(Direction.NORTH) + player.message("You pull yourself through the pipes..", ChatType.Filter) + pause() + player.setAnimation("climb_through_pipe") + player.exactMove(target.tile.addY(2)) + pause(4) + player.face(Direction.NORTH) + player.tele(target.tile.addY(3)) + player.setAnimation("climb_through_pipe", delay = 1) + player.exactMove(target.tile.addY(6)) + pause(2) + if (player.gnomeStage == 6) { + player.gnomeStage = 0 + player.inc("gnome_course_laps") + player.exp(Skill.Agility, 39.0) + } + player.exp(Skill.Agility, 7.5) + } +} \ No newline at end of file diff --git a/game/src/main/kotlin/world/gregs/voidps/world/activity/skill/agility/course/GnomeTrainer.kts b/game/src/main/kotlin/world/gregs/voidps/world/activity/skill/agility/course/GnomeTrainer.kts new file mode 100644 index 000000000..b8b83ad87 --- /dev/null +++ b/game/src/main/kotlin/world/gregs/voidps/world/activity/skill/agility/course/GnomeTrainer.kts @@ -0,0 +1,67 @@ +package world.gregs.voidps.world.activity.skill.agility.course + +import world.gregs.voidps.engine.client.message +import world.gregs.voidps.engine.entity.character.npc.npcOperate +import world.gregs.voidps.engine.entity.character.player.chat.inventoryFull +import world.gregs.voidps.engine.entity.character.player.skill.Skill +import world.gregs.voidps.engine.entity.character.player.skill.level.Level.has +import world.gregs.voidps.engine.inv.add +import world.gregs.voidps.engine.inv.inventory +import world.gregs.voidps.type.random +import world.gregs.voidps.world.interact.dialogue.Happy +import world.gregs.voidps.world.interact.dialogue.Quiz +import world.gregs.voidps.world.interact.dialogue.Talk +import world.gregs.voidps.world.interact.dialogue.type.choice +import world.gregs.voidps.world.interact.dialogue.type.npc +import world.gregs.voidps.world.interact.dialogue.type.player + +npcOperate("Talk-to", "gnome_trainer") { + when (random.nextInt(2)) { + 0 -> npc("This is training, soldier. Little time for chat! What do you want?") + 1 -> npc("This is a serious training area. What do you want?") + 2 -> npc("This isn't a grannies' tea party. What do you want?") + } + choice("What do you want to say?") { + option("What is this place?") { + npc("This, my friend, is where we train and improve our Agility. It's an essential skill.") + player("It looks easy enough.") + npc("If you complete the course, from the slippery log to the end, your Agility will increase more rapidly than by repeating just one obstacle.") + } + option("What's so special about this course, then?") { + npc("Well, it's where most people tend to start training. We've also made an extension for those who are up for the challenge.") + player("An extension?") + if (player.has(Skill.Agility, 85)) { + npc("Well, you look like you can handle it, so I'll fill you in. If you follow the course as normal, you'll see a new branch before the balancing rope. This is the way up to the new route. It's taken a while to strengthen the branch, but you should find yourself agile enough to get up to the next level. I suggest you check it out.") + player("I might just do that. Anything else I need to know?") + npc("Yes. If you do the tougher route, you'll get a much larger experience bonus at the end of it - just make sure you've completed all the obstacles leading up to the branch! Oh, I nearly forgot: if you manage to do 250 laps of the advanced route without a fault, we'll give you a special item. We'll keep a tally of your laps, so you can always check your progress.") + } else { + npc("It's a challenge that I think is a bit out of your depth. I'll give you more information when you're slightly more experienced.") + player.message("You need an Agility level of 85 to attempt the improved gnome course.") + } + } + option("Can I talk about rewards?", filter = { player["gnome_course_advanced_laps", 0] > 0 }) { + if (player["gnome_course_reward_claimed", false]) { + npc("Of course. How can I help?") + player("Any chance of some more Agile legs?") + if (player.inventory.add("agile_legs")) { + npc("Here you go, try not to lose them.") + } else { + player.inventoryFull() // TODO correct message + } + } else if (player["gnome_course_advanced_laps", 0] >= 250) { + npc("Well, it looks like you've completed our challenge! Take this as a reward: some Agile legs. You'll find yourself much lighter than usual while wearing them. They are made from the toughest material we gnomes could find, so it might even protect you in combat.") + if (player.inventory.add("agile_legs")) { + player["gnome_course_reward_claimed"] = true + npc("There you go. Enjoy!") + } else { + player.inventoryFull() // TODO correct message + } + } else { + npc("Well, you've still got work to do. Your lap count is ${player["gnome_course_advanced_laps", 0]}. It's 250 successful laps for the reward!") + } + } + option("I'm done for now. Bye.") { + npc("Bye for now. Come back if you need any assistance.") + } + } +} \ No newline at end of file diff --git a/game/src/main/kotlin/world/gregs/voidps/world/command/debug/PlayerUpdatingCommands.kts b/game/src/main/kotlin/world/gregs/voidps/world/command/debug/PlayerUpdatingCommands.kts index a4dc1f92e..b0950d8a8 100644 --- a/game/src/main/kotlin/world/gregs/voidps/world/command/debug/PlayerUpdatingCommands.kts +++ b/game/src/main/kotlin/world/gregs/voidps/world/command/debug/PlayerUpdatingCommands.kts @@ -54,8 +54,8 @@ adminCommand("anim") { adminCommand("emote") { when (content) { - "-1", "" -> player.emote = "human_stand" - else -> player.emote = content + "-1", "" -> player.renderEmote = "human_stand" + else -> player.renderEmote = content } } diff --git a/game/src/test/kotlin/world/gregs/voidps/world/activity/skill/agility/course/GnomeAdvancedTest.kt b/game/src/test/kotlin/world/gregs/voidps/world/activity/skill/agility/course/GnomeAdvancedTest.kt new file mode 100644 index 000000000..d1dcdcde2 --- /dev/null +++ b/game/src/test/kotlin/world/gregs/voidps/world/activity/skill/agility/course/GnomeAdvancedTest.kt @@ -0,0 +1,85 @@ +package world.gregs.voidps.world.activity.skill.agility.course + +import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.Test +import world.gregs.voidps.engine.entity.character.player.skill.Skill +import world.gregs.voidps.type.Tile +import world.gregs.voidps.world.script.* + +internal class GnomeAdvancedTest : WorldTest() { + + @Test + fun `Climb up advanced branch`() { + val player = createPlayer("agile", Tile(2472, 3420, 2)) + player.levels.set(Skill.Agility, 85) + val branch = objects[Tile(2472, 3419, 2), "gnome_tree_branch_advanced"]!! + + player.objectOption(branch, "Climb-up") + tick(3) + + assertEquals(Tile(2472, 3419, 3), player.tile) + assertEquals(25.0, player.experience.get(Skill.Agility)) + } + + @Test + fun `Can't climb up advanced branch`() { + val player = createPlayer("agile", Tile(2472, 3420, 2)) + val branch = objects[Tile(2472, 3419, 2), "gnome_tree_branch_advanced"]!! + + player.objectOption(branch, "Climb-up") + tick(3) + + assertEquals(Tile(2472, 3420, 2), player.tile) + assertEquals(0.0, player.experience.get(Skill.Agility)) + } + + @Test + fun `Run across sign post`() { + val player = createPlayer("agile", Tile(2475, 3418, 3)) + val sign = objects[Tile(2478, 3417, 3), "gnome_sign_post_advanced"]!! + + player.objectOption(sign, "Run-across") + tick(8) + + assertEquals(Tile(2484, 3418, 3), player.tile) + assertEquals(25.0, player.experience.get(Skill.Agility)) + } + + @Test + fun `Swing across poles`() { + val player = createPlayer("agile", Tile(2485, 3418, 3)) + val pole = objects[Tile(2486, 3425, 3), "gnome_pole_advanced"]!! + + player.objectOption(pole, "Swing-to") + tick(16) + + assertEquals(Tile(2485, 3432, 3), player.tile) + assertEquals(25.0, player.experience.get(Skill.Agility)) + } + + @Test + fun `Jump over barrier`() { + val player = createPlayer("agile", Tile(2486, 3432, 3)) + val barrier = objects[Tile(2485, 3433, 3), "gnome_barrier_advanced"]!! + + player.objectOption(barrier, "Jump-over") + tick(4) + + assertEquals(Tile(2485, 3436), player.tile) + assertEquals(25.0, player.experience.get(Skill.Agility)) + } + + @Test + fun `Jump over barrier with bonus reward`() { + val player = createPlayer("agile", Tile(2486, 3432, 3)) + val barrier = objects[Tile(2485, 3433, 3), "gnome_barrier_advanced"]!! + player["gnome_course_stage"] = 6 + + player.objectOption(barrier, "Jump-over") + tick(4) + + assertEquals(Tile(2485, 3436), player.tile) + assertEquals(630.0, player.experience.get(Skill.Agility)) + } + +} \ No newline at end of file diff --git a/game/src/test/kotlin/world/gregs/voidps/world/activity/skill/agility/course/GnomeStrongholdTest.kt b/game/src/test/kotlin/world/gregs/voidps/world/activity/skill/agility/course/GnomeStrongholdTest.kt new file mode 100644 index 000000000..cfb5ae1fa --- /dev/null +++ b/game/src/test/kotlin/world/gregs/voidps/world/activity/skill/agility/course/GnomeStrongholdTest.kt @@ -0,0 +1,109 @@ +package world.gregs.voidps.world.activity.skill.agility.course + +import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.Test +import world.gregs.voidps.engine.entity.character.player.skill.Skill +import world.gregs.voidps.type.Tile +import world.gregs.voidps.world.script.* + +internal class GnomeStrongholdTest : WorldTest() { + + @Test + fun `Walk across balance log`() { + val player = createPlayer("agile", Tile(2474, 3437)) + val log = objects[Tile(2474, 3435), "gnome_log_balance"]!! + + player.objectOption(log, "Walk-across") + tick(10) + + assertEquals(Tile(2474, 3429), player.tile) + assertEquals(7.5, player.experience.get(Skill.Agility)) + } + + @Test + fun `Climb first obstacle net`() { + val player = createPlayer("agile", Tile(2475, 3426)) + val net = objects[Tile(2475, 3425), "gnome_obstacle_net"]!! + + player.objectOption(net, "Climb-over") + tick(3) + + assertEquals(Tile(2475, 3424, 1), player.tile) + assertEquals(7.5, player.experience.get(Skill.Agility)) + } + + @Test + fun `Climb first tree branch`() { + val player = createPlayer("agile", Tile(2474, 3422, 1)) + val branch = objects[Tile(2473, 3422, 1), "gnome_tree_branch_up"]!! + + player.objectOption(branch, "Climb") + tick(3) + + assertEquals(Tile(2473, 3420, 2), player.tile) + assertEquals(5.0, player.experience.get(Skill.Agility)) + } + + @Test + fun `Walk across tight rope`() { + val player = createPlayer("agile", Tile(2477, 3419, 2)) + val rope = objects[Tile(2478, 3420, 2), "gnome_balancing_rope"]!! + + player.objectOption(rope, "Walk-on") + tick(8) + + assertEquals(Tile(2483, 3420, 2), player.tile) + assertEquals(7.5, player.experience.get(Skill.Agility)) + } + + @Test + fun `Climb down tree branch`() { + val player = createPlayer("agile", Tile(2486, 3418, 2)) + val branch = objects[Tile(2486, 3419, 2), "gnome_tree_branch_down"]!! + + player.objectOption(branch, "Climb-down") + tick(3) + + assertEquals(Tile(2486, 3420), player.tile) + assertEquals(5.0, player.experience.get(Skill.Agility)) + } + + @Test + fun `Climb over netting`() { + val player = createPlayer("agile", Tile(2487, 3424)) + val net = objects[Tile(2487, 3426), "gnome_obstacle_net_free_standing"]!! + + player.objectOption(net, "Climb-over") + tick(3) + + assertEquals(Tile(2487, 3427), player.tile) + assertEquals(7.5, player.experience.get(Skill.Agility)) + } + + @Test + fun `Climb through pipe`() { + val player = createPlayer("agile", Tile(2488, 3431)) + val pipe = objects[Tile(2487, 3431), "gnome_obstacle_pipe_east"]!! + + player.objectOption(pipe, "Squeeze-through") + tick(10) + + assertEquals(Tile(2487, 3437), player.tile) + assertEquals(7.5, player.experience.get(Skill.Agility)) + } + + + @Test + fun `Climb through pipe with bonus reward`() { + val player = createPlayer("agile", Tile(2483, 3430)) + val pipe = objects[Tile(2483, 3431), "gnome_obstacle_pipe_west"]!! + player["gnome_course_stage"] = 6 + + player.objectOption(pipe, "Squeeze-through") + tick(10) + + assertEquals(Tile(2483, 3437), player.tile) + assertEquals(46.5, player.experience.get(Skill.Agility)) + } + +} \ No newline at end of file