diff --git a/data/area/fremennik_province/lunar_isle/lunar_isle.areas.toml b/data/area/fremennik_province/lunar_isle/lunar_isle.areas.toml index f2dbd5ba76..fb42529c4c 100644 --- a/data/area/fremennik_province/lunar_isle/lunar_isle.areas.toml +++ b/data/area/fremennik_province/lunar_isle/lunar_isle.areas.toml @@ -14,3 +14,7 @@ y = [3840, 3967] level = 0 tags = ["multi_combat", "penguin_area"] hint = "on a large crescent island." + +[lunar_isle] +x = [2048, 2175] +y = [3840, 3967] diff --git a/data/area/fremennik_province/lunar_isle/lunar_isle.combat.toml b/data/area/fremennik_province/lunar_isle/lunar_isle.combat.toml index c95e9f0217..939c17a896 100644 --- a/data/area/fremennik_province/lunar_isle/lunar_isle.combat.toml +++ b/data/area/fremennik_province/lunar_isle/lunar_isle.combat.toml @@ -5,29 +5,35 @@ defend_anim = "suqah_defend" death_anim = "suqah_death" [suqah.melee] -chance = 5 # Unknown chances +chance = 10 # Unknown chances range = 1 +condition = "no_protect_melee" anim = "suqah_attack" target_hit = { offense = "stab", max = 100 } [suqah.water] -chance = 1 +chance = 5 range = 8 +condition = "no_protect_magic" anim = "suqah_attack" -gfx = "water_wave" -projectile = "water_spell_cast" +target_sound = "water_wave_cast" +projectile = "water_wave" target_hit = { offense = "magic", max = 100 } impact_gfx = "water_wave_impact" +miss_sound = "spell_splash" [suqah.ice] chance = 1 range = 8 +condition = "no_protect_magic" anim = "suqah_attack" -target_sound = "ice_barrage_cast" +target_sound = "water_wave_cast" projectile = { id = "ice_barrage", end_height = 0 } target_hit = { offense = "magic", min = 100, max = 100 } impact_gfx = "ice_barrage_impact" impact_sound = "ice_barrage_impact" +miss_sound = "spell_splash" +impact_freeze = 10 [suqah_swords] clone = "suqah" diff --git a/data/area/fremennik_province/lunar_isle/lunar_isle.npcs.toml b/data/area/fremennik_province/lunar_isle/lunar_isle.npcs.toml index c8d36e5a26..80d7b1ece2 100644 --- a/data/area/fremennik_province/lunar_isle/lunar_isle.npcs.toml +++ b/data/area/fremennik_province/lunar_isle/lunar_isle.npcs.toml @@ -170,7 +170,7 @@ id = 5899 [cyrisus_2] id = 5900 -[captain_bentley_3] +[captain_bentley_after] id = 408 [cyrisus_3] diff --git a/data/area/fremennik_province/lunar_isle/lunar_isle.objs.toml b/data/area/fremennik_province/lunar_isle/lunar_isle.objs.toml index ad41fce9bf..4eeb0b8399 100644 --- a/data/area/fremennik_province/lunar_isle/lunar_isle.objs.toml +++ b/data/area/fremennik_province/lunar_isle/lunar_isle.objs.toml @@ -1,3 +1,15 @@ [bank_booth_lunar_isle] id = 16700 examine = "The bank teller will serve you from here." + +[lunar_isle_dock_ladder] +id = 16960 + +[lunar_isle_dock_ladder_top] +id = 16962 + +[lunar_isle_boat_ladder] +id = 16959 + +[lunar_isle_boat_ladder_top] +id = 16961 diff --git a/data/area/fremennik_province/lunar_isle/lunar_isle.teles.toml b/data/area/fremennik_province/lunar_isle/lunar_isle.teles.toml new file mode 100644 index 0000000000..f8325e4395 --- /dev/null +++ b/data/area/fremennik_province/lunar_isle/lunar_isle.teles.toml @@ -0,0 +1,19 @@ +[lunar_isle_dock_ladder] +option = "Climb" +tile = { x = 2118, y = 3894 } +to = { x = 2118, y = 3893, level = 1 } + +[lunar_isle_dock_ladder_top] +option = "Climb" +tile = { x = 2118, y = 3894, level = 1 } +to = { x = 2118, y = 3895 } + +[lunar_isle_boat_ladder] +option = "Climb" +tile = { x = 2127, y = 3893, level = 1 } +to = { x = 2128, y = 3893, level = 2 } + +[lunar_isle_boat_ladder_top] +option = "Climb" +tile = { x = 2127, y = 3893, level = 2 } +to = { x = 2126, y = 3893, level = 1 } diff --git a/data/area/fremennik_province/pirates_cove/pirates_cove.areas.toml b/data/area/fremennik_province/pirates_cove/pirates_cove.areas.toml index 9543b3866f..da49e262f4 100644 --- a/data/area/fremennik_province/pirates_cove/pirates_cove.areas.toml +++ b/data/area/fremennik_province/pirates_cove/pirates_cove.areas.toml @@ -3,3 +3,7 @@ x = [2176, 2239] y = [3776, 3839] level = 0 tags = ["multi_combat"] + +[pirates_cove] +x = [2176, 2239] +y = [3776, 3839] diff --git a/data/area/fremennik_province/pirates_cove/pirates_cove.npc-spawns.toml b/data/area/fremennik_province/pirates_cove/pirates_cove.npc-spawns.toml index 67e8d6bb76..1bd9d55ecb 100644 --- a/data/area/fremennik_province/pirates_cove/pirates_cove.npc-spawns.toml +++ b/data/area/fremennik_province/pirates_cove/pirates_cove.npc-spawns.toml @@ -16,7 +16,7 @@ spawns = [ { id = "pirate_pirates_cove", x = 2205, y = 3814 }, { id = "captain_bentley", x = 2222, y = 3796, level = 2, members = true }, { id = "birds_eye_jack", x = 2222, y = 3788, level = 1, members = true }, - { id = "lokar_searunner_pirates_cove", x = 2214, y = 3794 }, + { id = "lokar_searunner", x = 2214, y = 3794 }, { id = "cabin_boy", x = 2223, y = 3788, level = 3, members = true }, { id = "beefy_burns", x = 2222, y = 3789 }, { id = "eagle_eye_shultz", x = 2224, y = 3813, level = 2 }, diff --git a/data/area/fremennik_province/pirates_cove/pirates_cove.npcs.toml b/data/area/fremennik_province/pirates_cove/pirates_cove.npcs.toml index 12330852f1..69bbd3d614 100644 --- a/data/area/fremennik_province/pirates_cove/pirates_cove.npcs.toml +++ b/data/area/fremennik_province/pirates_cove/pirates_cove.npcs.toml @@ -13,7 +13,7 @@ categories = ["pirates"] respawn_delay = 25 examine = "Avast ye scurvy land lubbers!" -[lokar_searunner_pirates_cove] +[lokar_searunner_after] id = 4537 examine = "Either a very fremennikey pirate, or a very piratey fremennik." diff --git a/data/area/fremennik_province/pirates_cove/pirates_cove.teles.toml b/data/area/fremennik_province/pirates_cove/pirates_cove.teles.toml new file mode 100644 index 0000000000..1a20d5a600 --- /dev/null +++ b/data/area/fremennik_province/pirates_cove/pirates_cove.teles.toml @@ -0,0 +1,29 @@ +[lunar_isle_boat_ladder_top] +option = "Climb" +tile = { x = 2214, y = 3801, level = 2 } +to = { x = 2214, y = 3802, level = 1 } + +[lunar_isle_boat_ladder] +option = "Climb" +tile = { x = 2214, y = 3801, level = 1 } +to = { x = 2214, y = 3800, level = 2 } + +[lunar_isle_dock_ladder_top] +option = "Climb" +tile = { x = 2212, y = 3809, level = 1 } +to = { x = 2211, y = 3809 } + +[lunar_isle_dock_ladder] +option = "Climb" +tile = { x = 2212, y = 3809 } +to = { x = 2213, y = 3809, level = 1 } + +[lunar_isle_dock_ladder_top] +option = "Climb" +tile = { x = 2213, y = 3795, level = 1 } +to = { x = 2213, y = 3794 } + +[lunar_isle_dock_ladder] +option = "Climb" +tile = { x = 2213, y = 3795 } +to = { x = 2213, y = 3796, level = 1 } diff --git a/data/area/fremennik_province/rellekka/brine_rat_caverns/brine_rat_caverns.anims.toml b/data/area/fremennik_province/rellekka/brine_rat_cavern/brine_rat_cavern.anims.toml similarity index 73% rename from data/area/fremennik_province/rellekka/brine_rat_caverns/brine_rat_caverns.anims.toml rename to data/area/fremennik_province/rellekka/brine_rat_cavern/brine_rat_cavern.anims.toml index 0131b38685..3cb6e3cc1a 100644 --- a/data/area/fremennik_province/rellekka/brine_rat_caverns/brine_rat_caverns.anims.toml +++ b/data/area/fremennik_province/rellekka/brine_rat_cavern/brine_rat_cavern.anims.toml @@ -6,3 +6,6 @@ id = 6116 [brine_rat_attack] id = 6117 + +[olaf_boulder_push] +id = 6131 diff --git a/data/area/fremennik_province/rellekka/brine_rat_cavern/brine_rat_cavern.areas.toml b/data/area/fremennik_province/rellekka/brine_rat_cavern/brine_rat_cavern.areas.toml new file mode 100644 index 0000000000..6ed0bd6480 --- /dev/null +++ b/data/area/fremennik_province/rellekka/brine_rat_cavern/brine_rat_cavern.areas.toml @@ -0,0 +1,3 @@ +[brine_rat_cavern_entrance] +x = [2747, 2749] +y = [3732, 3733] \ No newline at end of file diff --git a/data/area/fremennik_province/rellekka/brine_rat_caverns/brine_rat_caverns.combat.toml b/data/area/fremennik_province/rellekka/brine_rat_cavern/brine_rat_cavern.combat.toml similarity index 100% rename from data/area/fremennik_province/rellekka/brine_rat_caverns/brine_rat_caverns.combat.toml rename to data/area/fremennik_province/rellekka/brine_rat_cavern/brine_rat_cavern.combat.toml diff --git a/data/area/fremennik_province/rellekka/brine_rat_caverns/brine_rat_caverns.drops.toml b/data/area/fremennik_province/rellekka/brine_rat_cavern/brine_rat_cavern.drops.toml similarity index 100% rename from data/area/fremennik_province/rellekka/brine_rat_caverns/brine_rat_caverns.drops.toml rename to data/area/fremennik_province/rellekka/brine_rat_cavern/brine_rat_cavern.drops.toml diff --git a/data/area/fremennik_province/rellekka/brine_rat_caverns/brine_rat_caverns.npc-spawns.toml b/data/area/fremennik_province/rellekka/brine_rat_cavern/brine_rat_cavern.npc-spawns.toml similarity index 96% rename from data/area/fremennik_province/rellekka/brine_rat_caverns/brine_rat_caverns.npc-spawns.toml rename to data/area/fremennik_province/rellekka/brine_rat_cavern/brine_rat_cavern.npc-spawns.toml index 8e8523b26f..52a64a8a63 100644 --- a/data/area/fremennik_province/rellekka/brine_rat_caverns/brine_rat_caverns.npc-spawns.toml +++ b/data/area/fremennik_province/rellekka/brine_rat_cavern/brine_rat_cavern.npc-spawns.toml @@ -26,5 +26,5 @@ spawns = [ { id = "brine_rat", x = 2708, y = 10131, members = true }, { id = "brine_rat", x = 2710, y = 10134, members = true }, { id = "brine_rat", x = 2712, y = 10132, members = true }, - { id = "boulder_brine_rat_caverns", x = 2691, y = 10124, members = true }, + { id = "olaf_cave_boulder", x = 2691, y = 10124, members = true }, ] diff --git a/data/area/fremennik_province/rellekka/brine_rat_caverns/brine_rat_caverns.npcs.toml b/data/area/fremennik_province/rellekka/brine_rat_cavern/brine_rat_cavern.npcs.toml similarity index 97% rename from data/area/fremennik_province/rellekka/brine_rat_caverns/brine_rat_caverns.npcs.toml rename to data/area/fremennik_province/rellekka/brine_rat_cavern/brine_rat_cavern.npcs.toml index d06d25824c..de56a47aac 100644 --- a/data/area/fremennik_province/rellekka/brine_rat_caverns/brine_rat_caverns.npcs.toml +++ b/data/area/fremennik_province/rellekka/brine_rat_cavern/brine_rat_cavern.npcs.toml @@ -76,6 +76,5 @@ respawn_delay = 30 drop_table = "brine_rat" examine = "Eww, a bald rat!" -[boulder_brine_rat_caverns] +[olaf_cave_boulder] id = 3708 - diff --git a/data/area/fremennik_province/rellekka/brine_rat_cavern/brine_rat_cavern.objs.toml b/data/area/fremennik_province/rellekka/brine_rat_cavern/brine_rat_cavern.objs.toml new file mode 100644 index 0000000000..9bdbf2520b --- /dev/null +++ b/data/area/fremennik_province/rellekka/brine_rat_cavern/brine_rat_cavern.objs.toml @@ -0,0 +1,5 @@ +[brine_rat_cavern_exit] +id = 23157 + +[brine_rat_cavern_exit_cave] +id = 23158 \ No newline at end of file diff --git a/data/area/fremennik_province/rellekka/brine_rat_cavern/brine_rat_cavern.sounds.toml b/data/area/fremennik_province/rellekka/brine_rat_cavern/brine_rat_cavern.sounds.toml new file mode 100644 index 0000000000..4a4ffd225c --- /dev/null +++ b/data/area/fremennik_province/rellekka/brine_rat_cavern/brine_rat_cavern.sounds.toml @@ -0,0 +1,5 @@ +[olaf_fall_into_cave] +id = 3553 + +[olaf_roll_boulder] +id = 3554 diff --git a/data/area/fremennik_province/rellekka/brine_rat_cavern/brine_rat_cavern.teles.toml b/data/area/fremennik_province/rellekka/brine_rat_cavern/brine_rat_cavern.teles.toml new file mode 100644 index 0000000000..966202cf0b --- /dev/null +++ b/data/area/fremennik_province/rellekka/brine_rat_cavern/brine_rat_cavern.teles.toml @@ -0,0 +1,10 @@ +[brine_rat_cavern_exit] +option = "Exit" +tile = { x = 2689, y = 10125 } +to = { x = 2729, y = 3734 } + + +[brine_rat_cavern_exit_cave] +option = "Exit" +tile = { x = 2689, y = 10124 } +to = { x = 2729, y = 3734 } \ No newline at end of file diff --git a/data/area/fremennik_province/rellekka/hunter_area/rellekka_hunter_area.npc-spawns.toml b/data/area/fremennik_province/rellekka/hunter_area/rellekka_hunter_area.npc-spawns.toml index 2e632e14ae..87c2b05196 100644 --- a/data/area/fremennik_province/rellekka/hunter_area/rellekka_hunter_area.npc-spawns.toml +++ b/data/area/fremennik_province/rellekka/hunter_area/rellekka_hunter_area.npc-spawns.toml @@ -63,6 +63,6 @@ spawns = [ { id = "gnoeals_2", x = 3423, y = 4377, members = true }, { id = "gnoeals_2", x = 3432, y = 4378, members = true }, { id = "gnoeals_2", x = 3432, y = 4395, members = true }, - { id = "erjolf", x = 2695, y = 3794, members = true }, + { id = "erjolf_base", x = 2695, y = 3794, members = true }, { id = "natural_historian_rellekka", x = 2735, y = 3824, level = 1, members = true }, ] diff --git a/data/area/fremennik_province/rellekka/hunter_area/rellekka_hunter_area.npcs.toml b/data/area/fremennik_province/rellekka/hunter_area/rellekka_hunter_area.npcs.toml index 6f1b396f90..b76e45089a 100644 --- a/data/area/fremennik_province/rellekka/hunter_area/rellekka_hunter_area.npcs.toml +++ b/data/area/fremennik_province/rellekka/hunter_area/rellekka_hunter_area.npcs.toml @@ -29,7 +29,7 @@ examine = "A strange, magical beast." [gnoeals_2] id = 7382 -[erjolf] +[erjolf_base] id = 7405 [natural_historian_rellekka] diff --git a/data/area/fremennik_province/rellekka/ice_strykewyrm_cave/ice_strykewyrm.combat.toml b/data/area/fremennik_province/rellekka/ice_strykewyrm_cave/ice_strykewyrm.combat.toml new file mode 100644 index 0000000000..6f22c25ac7 --- /dev/null +++ b/data/area/fremennik_province/rellekka/ice_strykewyrm_cave/ice_strykewyrm.combat.toml @@ -0,0 +1,37 @@ +[ice_strykewyrm] +attack_speed = 4 +retreat_range = 12 +defend_anim = "strykewyrm_defend" +defend_sound = "strykewyrm_defend" +death_anim = "strykewyrm_death" +death_sound = "strykewyrm_death" + +[ice_strykewyrm.melee] +chance = 8 +range = 1 +anim = "strykewyrm_attack" +target_hit = { offense = "stab", max = 170 } + +[ice_strykewyrm.magic] +chance = 8 +range = 8 +anim = "strykewyrm_shoot" +projectile = "ice_strykewyrm_travel" +projectile_origin_y = 1 +projectile_origin_x = 1 +impact_gfx = "ice_strykewyrm_impact" +target_hit = { offense = "magic", max = 170 } + +[ice_strykewyrm.freeze] +range = 8 +anim = "strykewyrm_shoot" +projectile = "ice_strykewyrm_travel" +projectile_origin_y = 1 +projectile_origin_x = 1 +impact_regardless = true +impact_gfx = "ice_barrage_impact" +target_hit = { offense = "magic", max = 170, accuracy_roll = false } +impact_freeze = 5 + +[ice_strykewyrm.dig] +range = 8 \ No newline at end of file diff --git a/data/area/fremennik_province/rellekka/ice_strykewyrm_cave/ice_strykewyrm.drops.toml b/data/area/fremennik_province/rellekka/ice_strykewyrm_cave/ice_strykewyrm.drops.toml new file mode 100644 index 0000000000..39c7b44475 --- /dev/null +++ b/data/area/fremennik_province/rellekka/ice_strykewyrm_cave/ice_strykewyrm.drops.toml @@ -0,0 +1,87 @@ +[ice_strykewyrm_drop_table] +type = "all" +drops = [ + { table = "ice_strykewyrm_secondary" }, + { table = "ice_strykewyrm_tertiary" }, + { table = "ice_strykewyrm_charms" }, +] + +[ice_strykewyrm_secondary] +roll = 512 +drops = [ + { id = "mithril_battleaxe", chance = 32 }, + { id = "rune_battleaxe", chance = 2 }, + { id = "rune_2h_sword", chance = 2 }, + { id = "staff_of_light", chance = 2 }, + { id = "rune_sq_shield", chance = 2 }, + { id = "dragon_med_helm", chance = 2 }, + { id = "blood_rune", amount = 15, chance = 8 }, + { id = "law_rune", min = 20, max = 45, chance = 8 }, + { id = "death_rune", min = 20, max = 45, chance = 8 }, + { id = "nature_rune", min = 60, max = 79 }, + { id = "water_talisman_noted", min = 1, max = 3, chance = 8 }, + { id = "earth_talisman", chance = 2 }, + { id = "mind_talisman", chance = 2 }, + { id = "fire_talisman", chance = 2 }, + { id = "body_talisman", chance = 2 }, + { id = "air_talisman", chance = 2 }, + { id = "cosmic_talisman", chance = 2 }, + { id = "steel_arrow", amount = 150 }, + { id = "rune_arrow", amount = 42 }, + { id = "adamant_javelin", amount = 5 }, + { id = "rune_bar_noted", chance = 8 }, + { id = "rune_bar", chance = 8 }, + { id = "grimy_guam_noted", min = 1, max = 4, chance = 32 }, + { id = "grimy_marrentill_noted", min = 1, max = 4, chance = 32 }, + { id = "grimy_tarromin_noted", min = 1, max = 4, chance = 32 }, + { id = "grimy_harralander_noted", min = 1, max = 4, chance = 32 }, + { id = "grimy_ranarr_noted", min = 1, max = 4, chance = 32 }, + { id = "grimy_irit_noted", min = 1, max = 4, chance = 32 }, + { id = "grimy_avantoe_noted", min = 1, max = 4, chance = 32 }, + { id = "grimy_kwuarm_noted", min = 1, max = 4, chance = 32 }, + { id = "grimy_cadantine_noted", min = 1, max = 4, chance = 8 }, + { id = "grimy_lantadyme_noted", min = 1, max = 4, chance = 8 }, + { id = "grimy_dwarf_weed_noted", min = 1, max = 4, chance = 8 }, + { id = "watermelon_seed", chance = 32 }, + { id = "cactus_seed", chance = 32 }, + { id = "ranarr_seed", chance = 32 }, + { id = "poison_ivy_seed", chance = 32 }, + { id = "kwuarm_seed", chance = 32 }, + { id = "toadflax_seed", chance = 32 }, + { id = "jangerberry_seed", chance = 32 }, + { id = "wildblood_seed", chance = 32 }, + { id = "belladonna_seed", chance = 32 }, + { id = "whiteberry_seed", chance = 32 }, + { id = "bittercap_mushroom_spore", chance = 32 }, + { id = "limpwurt_seed", chance = 8 }, + { id = "torstol_seed", chance = 2 }, + { id = "maple_seed", chance = 2 }, + { id = "spirit_weed_seed", chance = 2 }, + { id = "snapdragon_seed", chance = 2 }, + { id = "dwarf_weed_seed", chance = 2 }, + { id = "coins", min = 200, max = 8001, chance = 32 }, + { id = "shark", min = 1, max = 6, chance = 32 }, + { id = "crushed_nest_noted", min = 5, max = 9, chance = 32 }, + { id = "super_defence_3", chance = 32 }, + { id = "pure_essence_noted", amount = 200, chance = 32 }, + { id = "magic_logs_noted", amount = 5, chance = 32 }, + { table = "rare_drop_table", chance = 25 }, +] + +[ice_strykewyrm_tertiary] +roll = 512 +drops = [ + { table = "hard_clue_scroll", chance = 2 }, + { table = "elite_clue_scroll", chance = 2 }, + { id = "starved_ancient_effigy", chance = 2 }, + { id = "court_summons" }, +] + +[ice_strykewyrm_charms] +roll = 1000 +drops = [ + { id = "gold_charm", chance = 56 }, + { id = "green_charm", chance = 28 }, + { id = "crimson_charm", chance = 22 }, + { id = "blue_charm", chance = 90 }, +] \ No newline at end of file diff --git a/data/area/fremennik_province/rellekka/ice_strykewyrm_cave/ice_strykewyrm.gfx.toml b/data/area/fremennik_province/rellekka/ice_strykewyrm_cave/ice_strykewyrm.gfx.toml new file mode 100644 index 0000000000..1f27cf33f2 --- /dev/null +++ b/data/area/fremennik_province/rellekka/ice_strykewyrm_cave/ice_strykewyrm.gfx.toml @@ -0,0 +1,8 @@ +[ice_strykewyrm_travel] +id = 2314 +curve = 16 +delay = 30 +# startHeight = 41, endHeight = 16, delay = 30, speed = 2 + +[ice_strykewyrm_impact] +id = 2315 \ No newline at end of file diff --git a/data/area/fremennik_province/rellekka/ice_strykewyrm_cave/ice_strykewyrm_cave.npcs.toml b/data/area/fremennik_province/rellekka/ice_strykewyrm_cave/ice_strykewyrm_cave.npcs.toml index e69de29bb2..16d3b7ab48 100644 --- a/data/area/fremennik_province/rellekka/ice_strykewyrm_cave/ice_strykewyrm_cave.npcs.toml +++ b/data/area/fremennik_province/rellekka/ice_strykewyrm_cave/ice_strykewyrm_cave.npcs.toml @@ -0,0 +1,22 @@ +[mound_ice_strykewyrm] +id = 9462 +hitpoints = 3000 +solid = false +allowed_under = true +# Made up stats +att = 225 +str = 225 +def = 175 +magic = 250 +attack_bonus = 100 +slayer_level = 93 +slayer_xp = 300.0 +height = 60 +drop_table = "ice_strykewyrm" +categories = ["ice_strykewyrm", "strykewyrm"] +examine = "I'm pretty sure there's something big under there." + +[ice_strykewyrm] +id = 9463 +combat_def = "ice_strykewyrm" +examine = "Now that's just cold." \ No newline at end of file diff --git a/data/area/fremennik_province/rellekka/ice_strykewyrm_cave/ice_styrkewyrm_cave.npc-spawns.toml b/data/area/fremennik_province/rellekka/ice_strykewyrm_cave/ice_styrkewyrm_cave.npc-spawns.toml index 3029158166..d4f1609e0c 100644 --- a/data/area/fremennik_province/rellekka/ice_strykewyrm_cave/ice_styrkewyrm_cave.npc-spawns.toml +++ b/data/area/fremennik_province/rellekka/ice_strykewyrm_cave/ice_styrkewyrm_cave.npc-spawns.toml @@ -1,14 +1,14 @@ spawns = [ - { id = "mound_wilderness", x = 3412, y = 5675, members = true }, - { id = "mound_wilderness", x = 3413, y = 5667, members = true }, - { id = "mound_wilderness", x = 3415, y = 5654, members = true }, - { id = "mound_wilderness", x = 3419, y = 5661, members = true }, - { id = "mound_wilderness", x = 3421, y = 5674, members = true }, - { id = "mound_wilderness", x = 3423, y = 5654, members = true }, - { id = "mound_wilderness", x = 3423, y = 5667, members = true }, - { id = "mound_wilderness", x = 3426, y = 5679, members = true }, - { id = "mound_wilderness", x = 3430, y = 5652, members = true }, - { id = "mound_wilderness", x = 3430, y = 5660, members = true }, - { id = "mound_wilderness", x = 3432, y = 5673, members = true }, - { id = "mound_wilderness", x = 3437, y = 5665, members = true }, + { id = "mound_ice_strykewyrm", x = 3412, y = 5675, members = true }, + { id = "mound_ice_strykewyrm", x = 3413, y = 5667, members = true }, + { id = "mound_ice_strykewyrm", x = 3415, y = 5654, members = true }, + { id = "mound_ice_strykewyrm", x = 3419, y = 5661, members = true }, + { id = "mound_ice_strykewyrm", x = 3421, y = 5674, members = true }, + { id = "mound_ice_strykewyrm", x = 3423, y = 5654, members = true }, + { id = "mound_ice_strykewyrm", x = 3423, y = 5667, members = true }, + { id = "mound_ice_strykewyrm", x = 3426, y = 5679, members = true }, + { id = "mound_ice_strykewyrm", x = 3430, y = 5652, members = true }, + { id = "mound_ice_strykewyrm", x = 3430, y = 5660, members = true }, + { id = "mound_ice_strykewyrm", x = 3432, y = 5673, members = true }, + { id = "mound_ice_strykewyrm", x = 3437, y = 5665, members = true }, ] diff --git a/data/area/fremennik_province/rellekka/rellekka.npcs.toml b/data/area/fremennik_province/rellekka/rellekka.npcs.toml index 62e24ba8ea..0dea503edb 100644 --- a/data/area/fremennik_province/rellekka/rellekka.npcs.toml +++ b/data/area/fremennik_province/rellekka/rellekka.npcs.toml @@ -436,8 +436,9 @@ id = 2437 [general_khazard_rellekka_2] id = 5566 -[erjolf_rellekka_2] +[erjolf] id = 7462 +dialogue = "child" [larry_rellekka_3] id = 5425 diff --git a/data/area/fremennik_province/rellekka/rellekka.objs.toml b/data/area/fremennik_province/rellekka/rellekka.objs.toml index 80e6995447..685803839c 100644 --- a/data/area/fremennik_province/rellekka/rellekka.objs.toml +++ b/data/area/fremennik_province/rellekka/rellekka.objs.toml @@ -38,3 +38,20 @@ examine = "Used for spinning thread." id = 4310 examine = "Used for fashioning clay items." +[ice_strykewyrm_cave_entrance] +id = 48188 + +[ice_strykewyrm_cave_exit] +id = 48189 + +[erjolf_cave_opening] +id = 42794 + +[erjolf_cave_opening_exit] +id = 42795 + +[erjolf_cave_exit] +id = 42891 + +[erjolf_cave_entrance] +id = 42793 \ No newline at end of file diff --git a/data/area/fremennik_province/rellekka/rellekka.teles.toml b/data/area/fremennik_province/rellekka/rellekka.teles.toml index fbf9a2f766..2bf1aaae76 100644 --- a/data/area/fremennik_province/rellekka/rellekka.teles.toml +++ b/data/area/fremennik_province/rellekka/rellekka.teles.toml @@ -46,4 +46,34 @@ delta = { level = -1 } [4188] option = "Climb-up" tile = { x = 2672, y = 10099, level = 2 } -to = { x = 2666, y = 3694 } \ No newline at end of file +to = { x = 2666, y = 3694 } + +[erjolf_cave_entrance] +option = "Enter" +tile = { x = 2737, y = 3729 } +to = { x = 3485, y = 5511 } + +[erjolf_cave_exit] +option = "Leave-cave" +tile = { x = 3484, y = 5509 } +to = { x = 2736, y = 3731 } + +[ice_strykewyrm_cave_entrance] +option = "Enter" +tile = { x = 3510, y = 5514 } +to = { x = 3435, y = 5646 } + +[ice_strykewyrm_cave_exit] +option = "Enter" +tile = { x = 3435, y = 5645 } +to = { x = 3509, y = 5515 } + +[erjolf_cave_opening] +option = "Enter" +tile = { x = 3470, y = 5524 } +to = { x = 3471, y = 5531 } + +[erjolf_cave_opening_exit] +option = "Enter" +tile = { x = 3470, y = 5529 } +to = { x = 3471, y = 5523 } diff --git a/data/area/kandarin/ancient_cavern/kuradals_dungeon/kuradals_dungeon.combat.toml b/data/area/kandarin/ancient_cavern/kuradals_dungeon/kuradals_dungeon.combat.toml index c453f3a77a..3ab3d7dbac 100644 --- a/data/area/kandarin/ancient_cavern/kuradals_dungeon/kuradals_dungeon.combat.toml +++ b/data/area/kandarin/ancient_cavern/kuradals_dungeon/kuradals_dungeon.combat.toml @@ -13,7 +13,8 @@ target_sound = "dark_beast_attack" target_hit = { offense = "crush", max = 170 } [dark_beast.magic] -range = 1 +range = 8 +condition = "ranged_only" anim = "dark_beast_attack" target_sound = "dark_beast_attack" target_hit = { offense = "magic", max = 80 } diff --git a/data/area/kandarin/ancient_cavern/kuradals_dungeon/kuradals_dungeon.drops.toml b/data/area/kandarin/ancient_cavern/kuradals_dungeon/kuradals_dungeon.drops.toml index 0c3079df9e..ba4ee8e9c2 100644 --- a/data/area/kandarin/ancient_cavern/kuradals_dungeon/kuradals_dungeon.drops.toml +++ b/data/area/kandarin/ancient_cavern/kuradals_dungeon/kuradals_dungeon.drops.toml @@ -4,6 +4,7 @@ drops = [ { id = "big_bones" }, { table = "dark_beast_secondary" }, { table = "dark_beast_tertiary" }, + { table = "dark_beast_charms" }, ] [dark_beast_secondary] @@ -42,3 +43,12 @@ drops = [ { table = "elite_clue_scroll", chance = 4 }, { id = "curved_bone" }, ] + +[dark_beast_charms] +roll = 1000 +drops = [ + { id = "gold_charm", chance = 84 }, + { id = "green_charm", chance = 42 }, + { id = "crimson_charm", chance = 84 }, + { id = "blue_charm", chance = 134 }, +] diff --git a/data/area/kandarin/ancient_cavern/kuradals_dungeon/kuradals_dungeon.npcs.toml b/data/area/kandarin/ancient_cavern/kuradals_dungeon/kuradals_dungeon.npcs.toml index 4b2fc1729f..b1e9577b0e 100644 --- a/data/area/kandarin/ancient_cavern/kuradals_dungeon/kuradals_dungeon.npcs.toml +++ b/data/area/kandarin/ancient_cavern/kuradals_dungeon/kuradals_dungeon.npcs.toml @@ -7,7 +7,7 @@ def = 120 mage = 160 combat_def = "dark_beast" xp_bonus = 2.5 -hunt_mode = "aggressive" +hunt_mode = "aggressive_intolerant" slayer_xp = 225.4 categories = ["dark_beasts"] respawn_delay = 50 diff --git a/data/area/kandarin/ardougne/east_ardougne.objs.toml b/data/area/kandarin/ardougne/east_ardougne.objs.toml index c462fdaeca..6d0035c051 100644 --- a/data/area/kandarin/ardougne/east_ardougne.objs.toml +++ b/data/area/kandarin/ardougne/east_ardougne.objs.toml @@ -170,3 +170,9 @@ examine = "An appliance used for cooking." [potters_wheel_ardougne] id = 34801 examine = "Used for fashioning clay items." + +[trapdoor_mourner_tunnels] +id = 8783 + +[ladder_mourner_tunnels] +id = 8785 \ No newline at end of file diff --git a/data/area/kandarin/ardougne/east_ardougne.teles.toml b/data/area/kandarin/ardougne/east_ardougne.teles.toml index 8e3670047b..67fe945f9b 100644 --- a/data/area/kandarin/ardougne/east_ardougne.teles.toml +++ b/data/area/kandarin/ardougne/east_ardougne.teles.toml @@ -261,4 +261,14 @@ to = { x = 2652, y = 3280, level = 1 } [34550] option = "Climb-down" tile = { x = 2650, y = 3280, level = 1 } -to = { x = 2649, y = 3280 } \ No newline at end of file +to = { x = 2649, y = 3280 } + +[trapdoor_mourner_tunnels] +option = "Open" +tile = { x = 2542, y = 3327 } +to = { x = 2044, y = 4649 } + +[ladder_mourner_tunnels] +option = "Climb-up" +tile = { x = 2044, y = 4650 } +to = { x = 2543, y = 3327 } diff --git a/data/area/kandarin/feldip_hills/feldip_hills.anims.toml b/data/area/kandarin/feldip_hills/feldip_hills.anims.toml new file mode 100644 index 0000000000..b1d4006184 --- /dev/null +++ b/data/area/kandarin/feldip_hills/feldip_hills.anims.toml @@ -0,0 +1,17 @@ +[strykewyrm_attack] +id = 12791 + +[strykewyrm_defend] +id = 12792 + +[strykewyrm_death] +id = 12793 + +[strykewyrm_shoot] +id = 12794 + +[strykewyrm_surface] +id = 12795 + +[strykewyrm_bury] +id = 12796 diff --git a/data/area/kandarin/feldip_hills/feldip_hills.combat.toml b/data/area/kandarin/feldip_hills/feldip_hills.combat.toml new file mode 100644 index 0000000000..91f5bf7a92 --- /dev/null +++ b/data/area/kandarin/feldip_hills/feldip_hills.combat.toml @@ -0,0 +1,36 @@ +[jungle_strykewyrm] +attack_speed = 4 +retreat_range = 12 +defend_anim = "strykewyrm_defend" +defend_sound = "strykewyrm_defend" +death_anim = "strykewyrm_death" +death_sound = "strykewyrm_death" + +[jungle_strykewyrm.melee] +chance = 5 +range = 1 +anim = "strykewyrm_attack" +target_hit = { offense = "stab", max = 90 } + +[jungle_strykewyrm.poison] +clone = "jungle_strykewyrm.melee" +impact_poison = 44 +impact_gfx = "jungle_strykewyrm_poison" + +[jungle_strykewyrm.magic] +chance = 5 +range = 8 +anim = "strykewyrm_shoot" +projectile = "jungle_strykewyrm_travel" +projectile_origin_y = 1 +projectile_origin_x = 1 +impact_gfx = "jungle_strykewyrm_impact" +target_hit = { offense = "magic", max = 88 } + +[jungle_strykewyrm.cloud] +clone = "jungle_strykewyrm.magic" +impact_poison = 88 +target_hit = { offense = "magic", max = 0 } + +[jungle_strykewyrm.dig] +range = 8 \ No newline at end of file diff --git a/data/area/kandarin/feldip_hills/feldip_hills.drops.toml b/data/area/kandarin/feldip_hills/feldip_hills.drops.toml new file mode 100644 index 0000000000..729aa573f1 --- /dev/null +++ b/data/area/kandarin/feldip_hills/feldip_hills.drops.toml @@ -0,0 +1,87 @@ +[jungle_strykewyrm_drop_table] +type = "all" +drops = [ + { table = "jungle_strykewyrm_secondary" }, + { table = "jungle_strykewyrm_tertiary" }, + { table = "jungle_strykewyrm_charms" }, +] + +[jungle_strykewyrm_secondary] +roll = 512 +drops = [ + { id = "nature_rune", amount = 15, chance = 32 }, + { id = "death_rune", min = 5, max = 10, chance = 32 }, + { id = "law_rune", amount = 10, chance = 32 }, + { id = "soul_rune", amount = 20, chance = 8 }, + { id = "water_talisman", chance = 2 }, + { id = "air_talisman", chance = 2 }, + { id = "body_talisman", chance = 2 }, + { id = "fire_talisman", chance = 2 }, + { id = "mind_talisman", chance = 2 }, + { id = "cosmic_talisman", chance = 2 }, + { id = "earth_talisman", chance = 2 }, + { id = "chaos_talisman", chance = 2 }, + { id = "grimy_cadantine", min = 1, max = 4, chance = 32 }, + { id = "grimy_guam_noted", min = 1, max = 4, chance = 8 }, + { id = "grimy_marrentill_noted", min = 1, max = 4, chance = 8 }, + { id = "grimy_tarromin_noted", min = 1, max = 4, chance = 8 }, + { id = "grimy_irit_noted", min = 1, max = 4, chance = 8 }, + { id = "grimy_harralander_noted", min = 1, max = 4, chance = 8 }, + { id = "grimy_dwarf_weed_noted", min = 1, max = 4, chance = 8 }, + { id = "grimy_avantoe_noted", min = 1, max = 4, chance = 2 }, + { id = "grimy_lantadyme_noted", min = 1, max = 4, chance = 2 }, + { id = "grimy_ranarr_noted", min = 1, max = 4, chance = 2 }, + { id = "grimy_kwuarm_noted", min = 1, max = 4, chance = 2 }, + { id = "toadflax_seed", chance = 32 }, + { id = "limpwurt_seed", chance = 32 }, + { id = "marrentill_seed", chance = 8 }, + { id = "tarromin_seed", chance = 8 }, + { id = "whiteberry_seed", chance = 8 }, + { id = "watermelon_seed", chance = 8 }, + { id = "harralander_seed", chance = 8 }, + { id = "wildblood_seed", chance = 8 }, + { id = "bittercap_mushroom_spore", chance = 8 }, + { id = "cactus_seed", chance = 8 }, + { id = "poison_ivy_seed", chance = 8 }, + { id = "yew_seed", chance = 2 }, + { id = "snapdragon_seed", chance = 2 }, + { id = "jangerberry_seed", chance = 2 }, + { id = "ranarr_seed", chance = 2 }, + { id = "spirit_weed_seed", chance = 2 }, + { id = "strawberry_seed", chance = 2 }, + { id = "kwuarm_seed", chance = 2 }, + { id = "dwarf_weed_seed", chance = 2 }, + { id = "avantoe_seed", chance = 2 }, + { id = "maple_seed", chance = 2 }, + { id = "magic_seed" }, + { id = "torstol_seed" }, + { id = "lantadyme_seed" }, + { id = "adamant_hatchet", chance = 8 }, + { id = "mithril_battleaxe", chance = 8 }, + { id = "hexcrest", chance = 2 }, + { id = "coins", min = 200, max = 2465, chance = 32 }, + { id = "papaya_fruit_noted", min = 3, max = 10, chance = 32 }, + { id = "pure_essence_noted", amount = 40, chance = 32 }, + { id = "teak_logs_noted", amount = 20, chance = 32 }, + { id = "lobster", min = 1, max = 2, chance = 32 }, + { id = "super_defence_1", chance = 32 }, + { id = "mithril_bar_noted", amount = 5, chance = 8 }, + { table = "rare_drop_table", chance = 10 }, +] + +[jungle_strykewyrm_tertiary] +roll = 512 +drops = [ + { table = "hard_clue_scroll", chance = 2 }, + { id = "starved_ancient_effigy", chance = 2 }, + { table = "elite_clue_scroll" }, +] + +[jungle_strykewyrm_charms] +roll = 1000 +drops = [ + { id = "gold_charm", chance = 56 }, + { id = "green_charm", chance = 140 }, + { id = "crimson_charm", chance = 22 }, + { id = "blue_charm", chance = 11 }, +] \ No newline at end of file diff --git a/data/area/kandarin/feldip_hills/feldip_hills.gfx.toml b/data/area/kandarin/feldip_hills/feldip_hills.gfx.toml new file mode 100644 index 0000000000..5b15d85d21 --- /dev/null +++ b/data/area/kandarin/feldip_hills/feldip_hills.gfx.toml @@ -0,0 +1,11 @@ +[jungle_strykewyrm_travel] +id = 2312 +curve = 16 +delay = 30 +# startHeight = 41, endHeight = 16, delay = 30, speed = 2 + +[jungle_strykewyrm_impact] +id = 2313 + +[jungle_strykewyrm_poison] +id = 2309 diff --git a/data/area/kandarin/feldip_hills/feldip_hills.npcs.toml b/data/area/kandarin/feldip_hills/feldip_hills.npcs.toml index 77b59bcd8a..4e4b2c6679 100644 --- a/data/area/kandarin/feldip_hills/feldip_hills.npcs.toml +++ b/data/area/kandarin/feldip_hills/feldip_hills.npcs.toml @@ -83,6 +83,26 @@ id = 8659 [mound_feldip_hills] id = 9466 +hitpoints = 1100 +solid = false +allowed_under = true +# Made up stats +att = 150 +str = 150 +def = 100 +magic = 150 +attack_bonus = 60 +slayer_level = 73 +slayer_xp = 110.0 +height = 60 +drop_table = "jungle_strykewyrm" +categories = ["jungle_strykewyrm", "strykewyrm"] +immune_poison = true + +[jungle_strykewyrm] +id = 9467 +combat_def = "jungle_strykewyrm" +examine = "Who said worms were small and harmless?" [swamp_toad_feldip_hills] id = 1013 diff --git a/data/area/kandarin/legends_guild/dungeon/legends_guild_dungeon.npcs.toml b/data/area/kandarin/legends_guild/dungeon/legends_guild_dungeon.npcs.toml index 76188c5219..f4dca3dc85 100644 --- a/data/area/kandarin/legends_guild/dungeon/legends_guild_dungeon.npcs.toml +++ b/data/area/kandarin/legends_guild/dungeon/legends_guild_dungeon.npcs.toml @@ -6,8 +6,7 @@ str = 33 def = 36 mage = 0 range = 0 -style = "slash" -max_hit_melee = 60 +combat_def = "ice_warrior" attack_bonus = 20 hunt_mode = "cowardly" slayer_xp = 67.0 diff --git a/data/area/kharidian_desert/al_kharid/al_kharid.shops.toml b/data/area/kharidian_desert/al_kharid/al_kharid.shops.toml index 7e7663ca58..586747221c 100644 --- a/data/area/kharidian_desert/al_kharid/al_kharid.shops.toml +++ b/data/area/kharidian_desert/al_kharid/al_kharid.shops.toml @@ -115,14 +115,14 @@ defaults = [ [alis_discount_wares_menaphite] id = 311 defaults = [ - { id = "menap_headgear_purple", amount = 30 }, + { id = "menaphite_headgear_purple", amount = 30 }, { id = "menaphite_top_purple", amount = 30 }, { id = "menaphite_robe_purple", amount = 30 }, - { id = "menap_action_kilt_purple", amount = 30 }, - { id = "menap_headgear_red", amount = 30 }, + { id = "menaphite_action_kilt_purple", amount = 30 }, + { id = "menaphite_headgear_red", amount = 30 }, { id = "menaphite_top_red", amount = 30 }, { id = "menaphite_robe_red", amount = 30 }, - { id = "menap_action_kilt_red", amount = 30 }, + { id = "menaphite_action_kilt_red", amount = 30 }, ] [alis_discount_wares_desert] diff --git a/data/area/kharidian_desert/al_kharid/desert_strykewyrm/desert_strykewyrm.combat.toml b/data/area/kharidian_desert/al_kharid/desert_strykewyrm/desert_strykewyrm.combat.toml new file mode 100644 index 0000000000..c678e63ba5 --- /dev/null +++ b/data/area/kharidian_desert/al_kharid/desert_strykewyrm/desert_strykewyrm.combat.toml @@ -0,0 +1,26 @@ +[desert_strykewyrm] +attack_speed = 4 +retreat_range = 12 +defend_anim = "strykewyrm_defend" +defend_sound = "strykewyrm_defend" +death_anim = "strykewyrm_death" +death_sound = "strykewyrm_death" + +[desert_strykewyrm.melee] +chance = 8 +range = 1 +anim = "strykewyrm_attack" +target_hit = { offense = "stab", max = 120 } + +[desert_strykewyrm.range] +chance = 8 +range = 8 +anim = "strykewyrm_shoot" +projectile = "desert_strykewyrm_travel" +projectile_origin_y = 1 +projectile_origin_x = 1 +impact_gfx = "desert_strykewyrm_impact" +target_hit = { offense = "range", defence = "magic", max = 125 } + +[desert_strykewyrm.dig] +range = 8 \ No newline at end of file diff --git a/data/area/kharidian_desert/al_kharid/desert_strykewyrm/desert_strykewyrm.drops.toml b/data/area/kharidian_desert/al_kharid/desert_strykewyrm/desert_strykewyrm.drops.toml new file mode 100644 index 0000000000..bd524c4ef9 --- /dev/null +++ b/data/area/kharidian_desert/al_kharid/desert_strykewyrm/desert_strykewyrm.drops.toml @@ -0,0 +1,83 @@ +[desert_strykewyrm_drop_table] +type = "all" +drops = [ + { table = "desert_strykewyrm_secondary" }, + { table = "desert_strykewyrm_tertiary" }, + { table = "desert_strykewyrm_charms" }, +] + +[desert_strykewyrm_secondary] +roll = 512 +drops = [ + { id = "death_rune", amount = 15, chance = 8 }, + { id = "water_rune", min = 2, max = 100, chance = 8 }, + { id = "law_rune", amount = 15, chance = 8 }, + { id = "air_talisman", chance = 8 }, + { id = "earth_talisman", chance = 8 }, + { id = "body_talisman", chance = 2 }, + { id = "mind_talisman", chance = 2 }, + { id = "cosmic_talisman", chance = 2 }, + { id = "fire_talisman", chance = 2 }, + { id = "mithril_battleaxe", chance = 32 }, + { id = "rune_hatchet", chance = 8 }, + { id = "focus_sight", chance = 2 }, + { id = "shield_left_half" }, + { id = "cadantine_seed", chance = 32 }, + { id = "avantoe_seed", chance = 8 }, + { id = "kwuarm_seed", chance = 8 }, + { id = "toadflax_seed", chance = 8 }, + { id = "irit_seed", chance = 8 }, + { id = "watermelon_seed", chance = 8 }, + { id = "poison_ivy_seed", chance = 8 }, + { id = "belladonna_seed", chance = 8 }, + { id = "cactus_seed", chance = 8 }, + { id = "lantadyme_seed", chance = 8 }, + { id = "snapdragon_seed", chance = 2 }, + { id = "dwarf_weed_seed", chance = 2 }, + { id = "yew_seed", chance = 2 }, + { id = "magic_seed", chance = 2 }, + { id = "torstol_seed", chance = 2 }, + { id = "maple_seed" }, + { id = "grimy_guam_noted", min = 1, max = 4, chance = 8 }, + { id = "grimy_marrentill_noted", min = 1, max = 4, chance = 8 }, + { id = "grimy_lantadyme_noted", min = 1, max = 4, chance = 8 }, + { id = "grimy_avantoe_noted", min = 1, max = 4, chance = 8 }, + { id = "grimy_cadantine_noted", min = 1, max = 4, chance = 8 }, + { id = "grimy_dwarf_weed_noted", min = 1, max = 4, chance = 8 }, + { id = "grimy_harralander_noted", min = 1, max = 4, chance = 8 }, + { id = "grimy_toadflax_noted", min = 1, max = 4, chance = 8 }, + { id = "grimy_irit_noted", min = 1, max = 4, chance = 8 }, + { id = "grimy_kwuarm_noted", min = 1, max = 4, chance = 8 }, + { id = "grimy_ranarr_noted", min = 1, max = 4, chance = 8 }, + { id = "grimy_tarromin_noted", min = 1, max = 4, chance = 8 }, + { id = "coins", amount = 200, chance = 32 }, + { id = "coins", amount = 240, chance = 32 }, + { id = "coins", amount = 400, chance = 32 }, + { id = "coins", min = 1200, max = 4500, chance = 32 }, + { id = "waterskin_4", amount = 2, chance = 32 }, + { id = "super_defence_2", chance = 32 }, + { id = "potato_cactus_noted", min = 5, max = 10, chance = 32 }, + { id = "yew_logs_noted", amount = 10, chance = 32 }, + { id = "pure_essence_noted", amount = 120, chance = 32 }, + { id = "swordfish", amount = 2, chance = 8 }, + { id = "adamant_bar_noted", amount = 3, chance = 8 }, + { table = "rare_drop_table", chance = 22 }, +] + +[desert_strykewyrm_tertiary] +roll = 512 +drops = [ + { table = "hard_clue_scroll", chance = 2 }, + { id = "starved_ancient_effigy", chance = 2 }, + { id = "court_summons", chance = 2 }, + { table = "elite_clue_scroll" }, +] + +[desert_strykewyrm_charms] +roll = 1000 +drops = [ + { id = "gold_charm", chance = 37 }, + { id = "green_charm", chance = 19 }, + { id = "crimson_charm", chance = 119 }, + { id = "blue_charm", chance = 7 }, +] \ No newline at end of file diff --git a/data/area/kharidian_desert/al_kharid/desert_strykewyrm/desert_strykewyrm.gfx.toml b/data/area/kharidian_desert/al_kharid/desert_strykewyrm/desert_strykewyrm.gfx.toml new file mode 100644 index 0000000000..b0af736c33 --- /dev/null +++ b/data/area/kharidian_desert/al_kharid/desert_strykewyrm/desert_strykewyrm.gfx.toml @@ -0,0 +1,8 @@ +[desert_strykewyrm_travel] +id = 2310 +curve = 16 +delay = 30 +# startHeight = 41, endHeight = 16, delay = 30, speed = 2 + +[desert_strykewyrm_impact] +id = 2311 \ No newline at end of file diff --git a/data/area/kharidian_desert/al_kharid/desert_strykewyrm/desert_strykewyrm.npcs.toml b/data/area/kharidian_desert/al_kharid/desert_strykewyrm/desert_strykewyrm.npcs.toml index f3f2746f29..f7d6f65efb 100644 --- a/data/area/kharidian_desert/al_kharid/desert_strykewyrm/desert_strykewyrm.npcs.toml +++ b/data/area/kharidian_desert/al_kharid/desert_strykewyrm/desert_strykewyrm.npcs.toml @@ -1,11 +1,24 @@ [mound_desert_strykewyrm] id = 9464 - -[ice_strykewyrm] -id = 9463 +hitpoints = 1200 +solid = false +allowed_under = true +# Made up stats +att = 175 +str = 175 +def = 125 +range = 200 +magic = 150 +attack_bonus = 80 +slayer_level = 77 +slayer_xp = 120.0 +height = 60 +drop_table = "desert_strykewyrm" +categories = ["desert_strykewyrm", "strykewyrm"] +examine = "I'm pretty sure there's something under there." [desert_strykewyrm] id = 9465 +combat_def = "desert_strykewyrm" +examine = "I dread to think of how many of these are in the sand." -[jungle_strykewyrm] -id = 9467 diff --git a/data/area/kharidian_desert/desert.items.toml b/data/area/kharidian_desert/desert.items.toml index 253a80a69b..0b4b93e3c4 100644 --- a/data/area/kharidian_desert/desert.items.toml +++ b/data/area/kharidian_desert/desert.items.toml @@ -100,7 +100,7 @@ examine = "Better than factor 50 sun cream." [desert_legs_noted] id = 6391 -[menap_headgear_purple] +[menaphite_headgear_purple] id = 6392 price = 475 limit = 100 @@ -109,7 +109,7 @@ slot = "Hat" type = "Hair" examine = "Good for keeping the sun off my neck." -[menap_headgear_purple_noted] +[menaphite_headgear_purple_noted] id = 6393 [menaphite_top_purple] @@ -134,7 +134,7 @@ examine = "A cool light Menaphite robe." [menaphite_robe_purple_noted] id = 6397 -[menap_action_kilt_purple] +[menaphite_action_kilt_purple] id = 6398 price = 265 limit = 100 @@ -142,10 +142,10 @@ weight = 0.005 slot = "Legs" examine = "Look at those nobbily knees." -[menap_action_kilt_purple_noted] +[menaphite_action_kilt_purple_noted] id = 6399 -[menap_headgear_red] +[menaphite_headgear_red] id = 6400 price = 443 limit = 100 @@ -154,7 +154,7 @@ slot = "Hat" type = "Hair" examine = "Good for keeping the sun off my neck." -[menap_headgear_red_noted] +[menaphite_headgear_red_noted] id = 6401 [menaphite_top_red] @@ -179,7 +179,7 @@ examine = "A cool light Menaphite robe." [menaphite_robe_red_noted] id = 6405 -[menap_action_kilt_red] +[menaphite_action_kilt_red] id = 6406 price = 249 limit = 100 @@ -187,7 +187,7 @@ weight = 0.005 slot = "Legs" examine = "Look at those nobbily knees." -[menap_action_kilt_red_noted] +[menaphite_action_kilt_red_noted] id = 6407 [oak_blackjack_o] diff --git a/data/area/kharidian_desert/desert.objs.toml b/data/area/kharidian_desert/desert.objs.toml index c427c9140b..9df0447e2e 100644 --- a/data/area/kharidian_desert/desert.objs.toml +++ b/data/area/kharidian_desert/desert.objs.toml @@ -4,4 +4,12 @@ examine = "Where does it go?" [desert_obelisk_ladder_up] id = 28740 -examine = "Going up?" \ No newline at end of file +examine = "Going up?" + +[desert_cactus_full] +id = 2670 +examine = "A succulent cactus." + +[desert_cactus_empty] +id = 2671 +examine = "A less-than-succulent succulent." \ No newline at end of file diff --git a/data/area/kharidian_desert/kharidian_desert.anims.toml b/data/area/kharidian_desert/kharidian_desert.anims.toml index b31ef144d8..5dd582a7b4 100644 --- a/data/area/kharidian_desert/kharidian_desert.anims.toml +++ b/data/area/kharidian_desert/kharidian_desert.anims.toml @@ -15,3 +15,6 @@ id = 3841 [goat_attack] id = 4936 + +[knife_chop] +id = 911 diff --git a/data/area/kharidian_desert/kharidian_desert.areas.toml b/data/area/kharidian_desert/kharidian_desert.areas.toml index f7ed071e14..f20794d0a3 100644 --- a/data/area/kharidian_desert/kharidian_desert.areas.toml +++ b/data/area/kharidian_desert/kharidian_desert.areas.toml @@ -5,7 +5,11 @@ tags = ["penguin_area"] hint = "in the north of the Kharidian desert." [south_kharidian_desert] -x = [3200,3200,3136,3136,3519,3519,3455,3455,3328,3328,3263,3263] -y = [2752,2880,2880,3071,3071,3008,3008,2752,2752,2816,2816,2752] +x = [3200, 3200, 3136, 3136, 3519, 3519, 3455, 3455, 3328, 3328, 3263, 3263] +y = [2752, 2880, 2880, 3071, 3071, 3008, 3008, 2752, 2752, 2816, 2816, 2752] tags = ["penguin_area"] hint = "in the south of the Kharidian desert." + +[kharidian_desert] +x = [3200, 3200, 3136, 3136, 3191, 3191, 3136, 3136, 3200, 3200, 3294, 3294, 3314, 3314, 3327, 3331, 3334, 3334, 3352, 3352, 3379, 3395, 3395, 3412, 3415, 3420, 3479, 3519, 3519, 3519, 3455, 3455, 3391, 3391, 3328, 3328, 3391, 3391, 3455, 3455, 3328, 3328, 3263, 3263] +y = [2752, 2880, 2880, 2960, 2960, 2999, 2999, 3071, 3071, 3135, 3135, 3116, 3116, 3135, 3135, 3139, 3148, 3158, 3158, 3148, 3124, 3148, 3163, 3163, 3173, 3173, 3141, 3136, 3071, 3008, 3008, 2944, 2944, 3007, 3007, 2944, 2944, 2879, 2879, 2752, 2752, 2816, 2816, 2752] diff --git a/data/area/kharidian_desert/kharidian_desert.combat.toml b/data/area/kharidian_desert/kharidian_desert.combat.toml index dd5b8c7ab2..26945b86bf 100644 --- a/data/area/kharidian_desert/kharidian_desert.combat.toml +++ b/data/area/kharidian_desert/kharidian_desert.combat.toml @@ -28,4 +28,3 @@ clone = "goat_kharidian_desert" [goat_kharidian_desert_2.melee] clone = "goat_kharidian_desert.melee" - diff --git a/data/area/kharidian_desert/kharidian_desert.enums.toml b/data/area/kharidian_desert/kharidian_desert.enums.toml new file mode 100644 index 0000000000..6f2d429889 --- /dev/null +++ b/data/area/kharidian_desert/kharidian_desert.enums.toml @@ -0,0 +1,29 @@ +[desert_heat_delay] +keyType = "item" +valueType = "int" +values = { + desert_disguise = 20, + desert_shirt = 20, + desert_robe = 20, + desert_boots = 20, + black_desert_shirt = 20, + black_desert_robe = 20, + fez = 20, + desert_top = 20, + desert_legs = 20, + desert_top_overcoat = 20, + desert_robes = 20, + slave_shirt = 10, + slave_robe = 10, + slave_boots = 10, + robe_of_elidinis_top = 20, + robe_of_elidinis_bottom = 20, + menaphite_headgear_purple = 20, + menaphite_top_purple = 20, + menaphite_robe_purple = 20, + menaphite_action_kilt_purple = 20, + menaphite_headgear_red = 20, + menaphite_top_red = 20, + menaphite_robe_red = 20, + menaphite_action_kilt_red = 20, +} \ No newline at end of file diff --git a/data/area/kharidian_desert/kharidian_desert.npcs.toml b/data/area/kharidian_desert/kharidian_desert.npcs.toml index d8f4acc972..2466929654 100644 --- a/data/area/kharidian_desert/kharidian_desert.npcs.toml +++ b/data/area/kharidian_desert/kharidian_desert.npcs.toml @@ -37,6 +37,11 @@ wander_range = 2 [desert_snake] id = 1874 +hitpoints = 60 +att = 4 +str = 5 +def = 3 +combat_def = "snake" examine = "A slithering serpent." [desert_phoenix_kharidian_desert] diff --git a/data/area/kharidian_desert/kharidian_desert.sounds.toml b/data/area/kharidian_desert/kharidian_desert.sounds.toml index 2d92760cf2..44c87255ad 100644 --- a/data/area/kharidian_desert/kharidian_desert.sounds.toml +++ b/data/area/kharidian_desert/kharidian_desert.sounds.toml @@ -6,3 +6,6 @@ id = 387 [crocodile_defend] id = 388 + +[sword_slash] +id = 2500 diff --git a/data/area/kharidian_desert/pollnivneach/pollnivneach.areas.toml b/data/area/kharidian_desert/pollnivneach/pollnivneach.areas.toml index 82db98e78a..bb0c249f39 100644 --- a/data/area/kharidian_desert/pollnivneach/pollnivneach.areas.toml +++ b/data/area/kharidian_desert/pollnivneach/pollnivneach.areas.toml @@ -7,3 +7,7 @@ tags = ["teleport", "scroll"] x = [3361, 3362] y = [2992, 2994] tags = ["teleport"] + +[smoke_dungeon] +x = [3200, 3327] +y = [9344, 9407] \ No newline at end of file diff --git a/data/area/kharidian_desert/pollnivneach/pollnivneach.objs.toml b/data/area/kharidian_desert/pollnivneach/pollnivneach.objs.toml new file mode 100644 index 0000000000..b810c29063 --- /dev/null +++ b/data/area/kharidian_desert/pollnivneach/pollnivneach.objs.toml @@ -0,0 +1,5 @@ +[smoke_dungeon_well] +id = 36002 + +[smoke_dungeon_rope] +id = 6439 diff --git a/data/area/kharidian_desert/pollnivneach/pollnivneach.teles.toml b/data/area/kharidian_desert/pollnivneach/pollnivneach.teles.toml new file mode 100644 index 0000000000..0df242809d --- /dev/null +++ b/data/area/kharidian_desert/pollnivneach/pollnivneach.teles.toml @@ -0,0 +1,9 @@ +[smoke_dungeon_well] +option = "Climb-down" +tile = { x = 3310, y = 2962 } +to = { x = 3206, y = 9379 } + +[smoke_dungeon_rope] +option = "Climb-up" +tile = { x = 3205, y = 9379 } +to = { x = 3310, y = 2961 } diff --git a/data/area/misthalin/lumbridge/swamp/caves/lumbridge_swamp_caves.anims.toml b/data/area/misthalin/lumbridge/swamp/caves/lumbridge_swamp_caves.anims.toml index aaae877c86..621348f321 100644 --- a/data/area/misthalin/lumbridge/swamp/caves/lumbridge_swamp_caves.anims.toml +++ b/data/area/misthalin/lumbridge/swamp/caves/lumbridge_swamp_caves.anims.toml @@ -40,3 +40,5 @@ id = 6002 [cave_goblin_death] id = 6003 +[insect_swarm] +id = 1582 diff --git a/data/area/misthalin/lumbridge/swamp/caves/lumbridge_swamp_caves.areas.toml b/data/area/misthalin/lumbridge/swamp/caves/lumbridge_swamp_caves.areas.toml index fdddbb52d3..02d9411c98 100644 --- a/data/area/misthalin/lumbridge/swamp/caves/lumbridge_swamp_caves.areas.toml +++ b/data/area/misthalin/lumbridge/swamp/caves/lumbridge_swamp_caves.areas.toml @@ -5,3 +5,35 @@ y = [9542, 9544] [lumbridge_swamp_east_fishing_area] x = [3245, 3249] y = [9568, 9572] + +[lumbridge_swamp_caves] +x = [3136, 3263] +y = [9536, 9602] + +[wall_beast_spot_1] +x = [3161] +y = [9546] + +[wall_beast_spot_2] +x = [3162] +y = [9573] + +[wall_beast_spot_3] +x = [3164] +y = [9555] + +[wall_beast_spot_4] +x = [3198] +y = [9553] + +[wall_beast_spot_5] +x = [3198] +y = [9571] + +[wall_beast_spot_6] +x = [3215] +y = [9559] + +[wall_beast_spot_7] +x = [3216] +y = [9587] diff --git a/data/area/misthalin/lumbridge/swamp/caves/lumbridge_swamp_caves.combat.toml b/data/area/misthalin/lumbridge/swamp/caves/lumbridge_swamp_caves.combat.toml index 36506221d9..ee87734612 100644 --- a/data/area/misthalin/lumbridge/swamp/caves/lumbridge_swamp_caves.combat.toml +++ b/data/area/misthalin/lumbridge/swamp/caves/lumbridge_swamp_caves.combat.toml @@ -22,6 +22,6 @@ death_sound = "wall_beast_death" [wall_beast.melee] range = 1 -anim = "wall_beast_attack" -target_sound = "wall_beast_attack" +anim = "wall_beast_swipe" +target_sound = "wall_beast_swipe" target_hit = { offense = "crush", max = 40 } diff --git a/data/area/misthalin/lumbridge/swamp/caves/lumbridge_swamp_caves.npc-spawns.toml b/data/area/misthalin/lumbridge/swamp/caves/lumbridge_swamp_caves.npc-spawns.toml index d9e866a496..e1a67c6e3b 100644 --- a/data/area/misthalin/lumbridge/swamp/caves/lumbridge_swamp_caves.npc-spawns.toml +++ b/data/area/misthalin/lumbridge/swamp/caves/lumbridge_swamp_caves.npc-spawns.toml @@ -58,13 +58,13 @@ spawns = [ { id = "cave_bug_larva", x = 3246, y = 9564 }, { id = "cave_bug_larva", x = 3250, y = 9579 }, { id = "cave_bug_larva", x = 3252, y = 9570 }, - { id = "hole_in_the_wall_lumbridge_swamp_caves", x = 3161, y = 9547 }, - { id = "hole_in_the_wall_lumbridge_swamp_caves", x = 3162, y = 9574 }, - { id = "hole_in_the_wall_lumbridge_swamp_caves", x = 3164, y = 9556 }, - { id = "hole_in_the_wall_lumbridge_swamp_caves", x = 3198, y = 9554 }, - { id = "hole_in_the_wall_lumbridge_swamp_caves", x = 3198, y = 9572 }, - { id = "hole_in_the_wall_lumbridge_swamp_caves", x = 3215, y = 9560 }, - { id = "hole_in_the_wall_lumbridge_swamp_caves", x = 3216, y = 9588 }, + { id = "hole_in_the_wall", x = 3161, y = 9547 }, + { id = "hole_in_the_wall", x = 3162, y = 9574 }, + { id = "hole_in_the_wall", x = 3164, y = 9556 }, + { id = "hole_in_the_wall", x = 3198, y = 9554 }, + { id = "hole_in_the_wall", x = 3198, y = 9572 }, + { id = "hole_in_the_wall", x = 3215, y = 9560 }, + { id = "hole_in_the_wall", x = 3216, y = 9588 }, { id = "fishing_spot_lumbridge_swamp_caves", x = 3154, y = 9544 }, { id = "fishing_spot_lumbridge_swamp_caves_2", x = 3245, y = 9570, members = true }, { id = "sergeant_mossfists_lumbridge_swamp_caves", x = 3168, y = 9572, members = true }, diff --git a/data/area/misthalin/lumbridge/swamp/caves/lumbridge_swamp_caves.npcs.toml b/data/area/misthalin/lumbridge/swamp/caves/lumbridge_swamp_caves.npcs.toml index 26bc9cc4be..2611f4493b 100644 --- a/data/area/misthalin/lumbridge/swamp/caves/lumbridge_swamp_caves.npcs.toml +++ b/data/area/misthalin/lumbridge/swamp/caves/lumbridge_swamp_caves.npcs.toml @@ -19,31 +19,22 @@ clone = "cave_goblin_lumbridge_swamp_caves" id = 1825 clone = "cave_goblin_lumbridge_swamp_caves" -[hole_in_the_wall_lumbridge_swamp_caves] +[hole_in_the_wall] id = 2058 hitpoints = 1050 att = 30 str = 30 def = 16 -combat_def = "wall_beast" -hunt_mode = "cowardly" +respawn_delay = 0 slayer_xp = 105.0 categories = ["wall_beasts"] immune_poison = true +drop_table = "wall_beast" examine = "What could be hiding in that crack in the wall?" [wall_beast] id = 7823 -hitpoints = 1050 -att = 30 -str = 30 -def = 16 combat_def = "wall_beast" -hunt_mode = "cowardly" -slayer_xp = 105.0 -categories = ["wall_beasts"] -immune_poison = true -drop_table = "wall_beast" examine = "A big, scary hand!" [fishing_spot_lumbridge_swamp_caves] diff --git a/data/area/morytania/mos_le_harmless/caves/mos_le_harmless.combat.toml b/data/area/morytania/mos_le_harmless/caves/mos_le_harmless.combat.toml deleted file mode 100644 index cd3e1c5cd2..0000000000 --- a/data/area/morytania/mos_le_harmless/caves/mos_le_harmless.combat.toml +++ /dev/null @@ -1,13 +0,0 @@ -[cave_horror] -retreat_range = 8 -attack_speed = 5 -defend_anim = "cave_horror_defend" -death_anim = "cave_horror_howl" -defend_sound = "jungle_horror_defend" -death_sound = "jungle_horror_death" - -[cave_horror.attack] -range = 1 -anim = "cave_horror_swing" -target_sound = "jungle_horror_attack" -target_hit = { offense = "crush", defence = "magic", max = 90 } \ No newline at end of file diff --git a/data/area/morytania/mos_le_harmless/caves/mos_le_harmless_caves.anims.toml b/data/area/morytania/mos_le_harmless/caves/mos_le_harmless_caves.anims.toml index 01cf8d7c3f..34948c04fe 100644 --- a/data/area/morytania/mos_le_harmless/caves/mos_le_harmless_caves.anims.toml +++ b/data/area/morytania/mos_le_harmless/caves/mos_le_harmless_caves.anims.toml @@ -9,3 +9,22 @@ id = 4235 [cave_horror_howl] id = 4237 + +[mosquito_defend] +id = 2399 + +[mosquito_death] +id = 2398 + +[mosquito_attack] +id = 2397 + +[jungle_horror_death] +id = 4233 + +[jungle_horror_defend] +id = 4232 + +[jungle_horror_attack] +id = 4234 + diff --git a/data/area/morytania/mos_le_harmless/caves/mos_le_harmless_caves.combat.toml b/data/area/morytania/mos_le_harmless/caves/mos_le_harmless_caves.combat.toml new file mode 100644 index 0000000000..7673bc41e5 --- /dev/null +++ b/data/area/morytania/mos_le_harmless/caves/mos_le_harmless_caves.combat.toml @@ -0,0 +1,51 @@ +[cave_horror] +retreat_range = 8 +attack_speed = 5 # TODO support irregular attack speeds/override +defend_anim = "cave_horror_defend" +death_anim = "cave_horror_howl" +defend_sound = "jungle_horror_defend" +death_sound = "jungle_horror_death" + +[cave_horror.attack] +range = 1 +anim = "cave_horror_swing" +target_sound = "jungle_horror_attack" +target_hit = { offense = "crush", defence = "magic", max = 90 } + +[cave_horror.howl] +condition = "witchwood_icon" +range = 1 +anim = "cave_horror_howl" +target_sound = "cave_horror_howl" +target_hit = { offense = "crush", defence = "magic", max = 90 } + +[cave_horror.special] +condition = "no_witchwood_icon" +range = 1 +anim = "cave_horror_howl" +target_sound = "cave_horror_howl" +target_hit = { offense = "crush", defence = "magic", min = 80, max = 90 } +# Copied from banshee's, not sure what actually drains as osrs works differently +impact_drains = [ + { skill = "attack", multiplier = 0.2 }, + { skill = "strength", multiplier = 0.2 }, + { skill = "defence", multiplier = 0.2 }, + { skill = "ranged", multiplier = 0.2 }, + { skill = "magic", multiplier = 0.2 }, + { skill = "prayer", multiplier = 0.1 }, + { skill = "agility", multiplier = 0.1 }, +] + +[giant_mosquito] +retreat_range = 8 +attack_speed = 12 +defend_anim = "mosquito_defend" +defend_sound = "mosquito_defend" +death_anim = "mosquito_death" +death_sound = "mosquito_death" + +[giant_mosquito.attack] +range = 1 +anim = "mosquito_attack" +target_sound = "mosquito_attack" +target_hit = { offense = "crush", max = 10 } diff --git a/data/area/morytania/mos_le_harmless/caves/mos_le_harmless_caves.npcs.toml b/data/area/morytania/mos_le_harmless/caves/mos_le_harmless_caves.npcs.toml index 75327b6d0e..fe2aca05fd 100644 --- a/data/area/morytania/mos_le_harmless/caves/mos_le_harmless_caves.npcs.toml +++ b/data/area/morytania/mos_le_harmless/caves/mos_le_harmless_caves.npcs.toml @@ -6,7 +6,7 @@ str = 57 def = 30 combat_def = "bat" max_hit_stab = 70 -hunt_mode = "cowardly" +hunt_mode = "aggressive" slayer_xp = 33.0 categories = ["bats"] respawn_delay = 35 diff --git a/data/area/morytania/mos_le_harmless/caves/mos_le_harmless_caves.sounds.toml b/data/area/morytania/mos_le_harmless/caves/mos_le_harmless_caves.sounds.toml index 0a09bd5788..99b22d8251 100644 --- a/data/area/morytania/mos_le_harmless/caves/mos_le_harmless_caves.sounds.toml +++ b/data/area/morytania/mos_le_harmless/caves/mos_le_harmless_caves.sounds.toml @@ -8,7 +8,16 @@ id = 497 id = 498 [jungle_horror_death] -id = 499 +id = 480 [jungle_horror_defend] id = 500 + +[mosquito_attack] +id = 637 + +[mosquito_defend] +id = 821 + +[mosquito_death] +id = 820 diff --git a/data/area/morytania/mos_le_harmless/mos_le_harmless.areas.toml b/data/area/morytania/mos_le_harmless/mos_le_harmless.areas.toml index 0073c29210..f847f1e3d9 100644 --- a/data/area/morytania/mos_le_harmless/mos_le_harmless.areas.toml +++ b/data/area/morytania/mos_le_harmless/mos_le_harmless.areas.toml @@ -2,4 +2,8 @@ x = [3648, 3853] y = [2880, 3071] tags = ["penguin_area"] -hint = "where pirates feel mostly harmless." \ No newline at end of file +hint = "where pirates feel mostly harmless." + +[mos_le_harmless_cave] +x = [3712, 3839] +y = [9344, 9741] \ No newline at end of file diff --git a/data/area/morytania/mos_le_harmless/mos_le_harmless.combat.toml b/data/area/morytania/mos_le_harmless/mos_le_harmless.combat.toml new file mode 100644 index 0000000000..a1745bbcd1 --- /dev/null +++ b/data/area/morytania/mos_le_harmless/mos_le_harmless.combat.toml @@ -0,0 +1,13 @@ +[jungle_horror] +retreat_range = 8 +attack_speed = 4 +defend_anim = "jungle_horror_defend" +defend_sound = "jungle_horror_defend" +death_anim = "jungle_horror_death" +death_sound = "jungle_horror_death" + +[jungle_horror.attack] +range = 1 +anim = "jungle_horror_attack" +target_sound = "jungle_horror_attack" +target_hit = { offense = "stab", defence = "magic", max = 80 } diff --git a/data/area/morytania/mos_le_harmless/mos_le_harmless.npcs.toml b/data/area/morytania/mos_le_harmless/mos_le_harmless.npcs.toml index 09c7167c78..a872149b96 100644 --- a/data/area/morytania/mos_le_harmless/mos_le_harmless.npcs.toml +++ b/data/area/morytania/mos_le_harmless/mos_le_harmless.npcs.toml @@ -114,9 +114,7 @@ id = 4347 hitpoints = 30 att = 5 def = 45 -attack_speed = 12 -style = "crush" -max_hit_melee = 10 +combat_def = "giant_mosquito" respawn_delay = 50 examine = "A flying blood sucker." @@ -126,8 +124,7 @@ hitpoints = 450 att = 70 str = 70 def = 55 -style = "stab" -max_hit_melee = 80 +combat_def = "jungle_horror" hunt_mode = "cowardly" slayer_xp = 45.0 categories = ["jungle_horrors"] diff --git a/data/area/morytania/mos_le_harmless/mos_le_harmless.objs.toml b/data/area/morytania/mos_le_harmless/mos_le_harmless.objs.toml index c7b8016b8d..571bbc424a 100644 --- a/data/area/morytania/mos_le_harmless/mos_le_harmless.objs.toml +++ b/data/area/morytania/mos_le_harmless/mos_le_harmless.objs.toml @@ -1,3 +1,12 @@ [bank_booth_mos_le_harmless] id = 11338 examine = "The bank teller will serve you from here." + +[cave_entrance_mos_le_harmless] +id = 15767 + +[cave_exit_mos_le_harmless] +id = 15811 + +[cave_exit_2_mos_le_harmless] +id = 15812 diff --git a/data/area/morytania/mos_le_harmless/mos_le_harmless.teles.toml b/data/area/morytania/mos_le_harmless/mos_le_harmless.teles.toml new file mode 100644 index 0000000000..88dd58d83e --- /dev/null +++ b/data/area/morytania/mos_le_harmless/mos_le_harmless.teles.toml @@ -0,0 +1,9 @@ +[cave_exit_mos_le_harmless] +option = "Exit" +tile = { x = 3749, y = 9373 } +to = { x = 3749, y = 2973 } + +[cave_exit_2_mos_le_harmless] +option = "Exit" +tile = { x = 3749, y = 9374 } +to = { x = 3749, y = 2973 } diff --git a/data/area/wilderness/chaos_tunnels/chaos_tunnels.combat.toml b/data/area/wilderness/chaos_tunnels/chaos_tunnels.combat.toml index f70ce5a973..068d9c23bd 100644 --- a/data/area/wilderness/chaos_tunnels/chaos_tunnels.combat.toml +++ b/data/area/wilderness/chaos_tunnels/chaos_tunnels.combat.toml @@ -22,9 +22,29 @@ death_sound = "dust_devil_death" [dust_devil.attack] range = 1 +condition = "face_mask" anim = "dust_devil_attack" +target_sound = "dust_devil_attack" target_hit = { offense = "melee", defence = "range", max = 80 } +[dust_devil.special] +range = 1 +condition = "no_face_mask" +projectile = "slayer_devil_dust" +anim = "dust_devil_attack" +target_sound = "dust_devil_attack" +target_hit = { offense = "melee", defence = "range", max = 160 } +impact_regardless = true +impact_drains = [ + { skill = "attack", multiplier = 1.0 }, + { skill = "strength", multiplier = 1.0 }, + { skill = "defence", multiplier = 0.5 }, + { skill = "ranged", multiplier = 1.0 }, + { skill = "magic", multiplier = 1.0 }, + { skill = "prayer", multiplier = 0.5 }, + { skill = "agility", multiplier = 0.5 }, +] + [giant_crypt_rat] attack_speed = 4 retreat_range = 8 diff --git a/data/area/wilderness/chaos_tunnels/chaos_tunnels.drops.toml b/data/area/wilderness/chaos_tunnels/chaos_tunnels.drops.toml index 547ddd0db5..66a8b8112b 100644 --- a/data/area/wilderness/chaos_tunnels/chaos_tunnels.drops.toml +++ b/data/area/wilderness/chaos_tunnels/chaos_tunnels.drops.toml @@ -84,3 +84,49 @@ drops = [ { id = "adamant_pickaxe", chance = 4 }, { id = "rune_pickaxe" }, ] +[dust_devil_drop_table] +type = "all" +drops = [ + { id = "bones" }, + { table = "dust_devil_secondary" }, + { table = "dust_devil_charms" }, +] + +[dust_devil_secondary] +roll = 32768 +drops = [ + { id = "adamant_hatchet", chance = 768 }, + { id = "rune_dagger", chance = 512 }, + { id = "red_dragonhide_vambraces", chance = 512 }, + { id = "black_dragonhide_vambraces", chance = 256 }, + { id = "air_battlestaff", chance = 512 }, + { id = "earth_battlestaff", chance = 512 }, + { id = "mystic_air_staff", chance = 256 }, + { id = "mystic_earth_staff", chance = 256 }, + { id = "dragon_dagger", chance = 256 }, + { id = "dragon_chainbody" }, + { id = "dust_rune", amount = 200, chance = 2560 }, + { id = "earth_rune", amount = 300, chance = 2560 }, + { id = "fire_rune", amount = 300, chance = 2560 }, + { id = "fire_rune", amount = 50, chance = 256 }, + { id = "chaos_rune", amount = 65, chance = 1792 }, + { id = "rune_arrow", amount = 12, chance = 1280 }, + { id = "soul_rune", amount = 15, chance = 1024 }, + { id = "soul_rune", amount = 50, chance = 256 }, + { table = "herb_drop_table", chance = 4864 }, + { id = "nothing", amount = 0, chance = 255 }, + { id = "coins", min = 2000, max = 4000, chance = 7168 }, + { id = "ugthanki_kebab", amount = 4, chance = 512 }, + { id = "mithril_bar_noted", amount = 10, chance = 768 }, + { id = "adamant_bar_noted", amount = 4, chance = 256 }, + { table = "gem_drop_table", chance = 2816 }, +] + +[dust_devil_charms] +roll = 1000 +drops = [ + { id = "gold_charm", chance = 121 }, + { id = "green_charm", chance = 60 }, + { id = "crimson_charm", chance = 243 }, + { id = "blue_charm", chance = 8 }, +] \ No newline at end of file diff --git a/data/area/wilderness/chaos_tunnels/chaos_tunnels.gfx.toml b/data/area/wilderness/chaos_tunnels/chaos_tunnels.gfx.toml new file mode 100644 index 0000000000..6a254ba5ba --- /dev/null +++ b/data/area/wilderness/chaos_tunnels/chaos_tunnels.gfx.toml @@ -0,0 +1,3 @@ +[slayer_devil_dust] +id = 73 +height = 50 \ No newline at end of file diff --git a/data/area/wilderness/wilderness.npcs.toml b/data/area/wilderness/wilderness.npcs.toml index c5b44e30b1..00e068d756 100644 --- a/data/area/wilderness/wilderness.npcs.toml +++ b/data/area/wilderness/wilderness.npcs.toml @@ -181,9 +181,6 @@ respawn_delay = 150 drop_table = "bones" examine = "He kills in the name of Guthix." -[mound_wilderness] -id = 9462 - [gull_wilderness] id = 9717 diff --git a/data/entity/npc/boss/giant_mole/giant_mole.drops.toml b/data/entity/npc/boss/giant_mole/giant_mole.drops.toml index afa9995f2e..c3c330a973 100644 --- a/data/entity/npc/boss/giant_mole/giant_mole.drops.toml +++ b/data/entity/npc/boss/giant_mole/giant_mole.drops.toml @@ -42,6 +42,6 @@ drops = [ roll = 10000 drops = [ { id = "long_bone", chance = 25 }, - { id = "clue_scroll_elite", lacks = "clue_scroll_elite*", chance = 20 }, + { table = "elite_clue_scroll", chance = 20 }, { id = "curved_bone", chance = 2}, ] diff --git a/data/entity/npc/boss/king_black_dragon/king_black_dragon.drops.toml b/data/entity/npc/boss/king_black_dragon/king_black_dragon.drops.toml index dc165b5370..e7bafa82ec 100644 --- a/data/entity/npc/boss/king_black_dragon/king_black_dragon.drops.toml +++ b/data/entity/npc/boss/king_black_dragon/king_black_dragon.drops.toml @@ -52,6 +52,6 @@ drops = [ [king_black_dragon_clues] roll = 10 drops = [ - { id = "clue_scroll_elite", chance = 4, lacks = "clue_scroll_elite*" }, + { table = "elite_clue_scroll", chance = 4 }, { table = "hard_clue_scroll" } ] diff --git a/data/entity/npc/monster/reptile/snake/snake.anims.toml b/data/entity/npc/monster/reptile/snake/snake.anims.toml new file mode 100644 index 0000000000..0fed2a6b13 --- /dev/null +++ b/data/entity/npc/monster/reptile/snake/snake.anims.toml @@ -0,0 +1,8 @@ +[snake_attack] +id = 275 + +[snake_defend] +id = 276 + +[snake_death] +id = 278 diff --git a/data/entity/npc/monster/reptile/snake/snake.combat.toml b/data/entity/npc/monster/reptile/snake/snake.combat.toml index ade6886116..385ef0b374 100644 --- a/data/entity/npc/monster/reptile/snake/snake.combat.toml +++ b/data/entity/npc/monster/reptile/snake/snake.combat.toml @@ -1,10 +1,13 @@ [snake] attack_speed = 4 retreat_range = 11 +defend_anim = "snake_defend" defend_sound = "snake_defend" +death_anim = "snake_death" death_sound = "snake_death" [snake.melee] range = 1 +anim = "snake_attack" target_sound = "snake_attack" target_hit = { offense = "stab", max = 10 } diff --git a/data/entity/obj/boat/charter_ship.areas.toml b/data/entity/obj/boat/charter_ship.areas.toml index a70b99a3ee..179ed60bd8 100644 --- a/data/entity/obj/boat/charter_ship.areas.toml +++ b/data/entity/obj/boat/charter_ship.areas.toml @@ -22,7 +22,7 @@ y = [3409, 3475, 3475, 3464, 3460, 3455, 3450, 3436, 3432, 3409] x = [2515, 2515, 2523, 2537, 2543, 2556, 2629, 2629, 2566, 2558, 2518] y = [2832, 2845, 2856, 2864, 2864, 2870, 2870, 2834, 2835, 2829, 2829] -[mos_le_harmless] +[mos_le_harmless_town] x = [3646, 3646, 3710, 3710, 3711, 3711] y = [2925, 3006, 3006, 2980, 2976, 2925] diff --git a/data/entity/player/modal/icon.items.toml b/data/entity/player/modal/icon.items.toml index 675b76fa5a..928c32f2b8 100644 --- a/data/entity/player/modal/icon.items.toml +++ b/data/entity/player/modal/icon.items.toml @@ -748,7 +748,7 @@ id = 14670 [erjolf] id = 14741 -examine = " Erjolf." +examine = "Erjolf." [leela] id = 14817 diff --git a/data/skill/agility/shortcut/shortcut.objs.toml b/data/skill/agility/shortcut/shortcut.objs.toml index 8d733a3943..51c0975eef 100644 --- a/data/skill/agility/shortcut/shortcut.objs.toml +++ b/data/skill/agility/shortcut/shortcut.objs.toml @@ -6,6 +6,10 @@ examine = "I can climb over the fence with this." id = 34776 examine = "I can climb over the fence with this." +[al_kharid_stile] +id = 48208 +examine = "I can climb over the fence with this." + [catherby_stile] id = 993 examine = "I can climb over the fence with this." diff --git a/data/skill/runecrafting/runecrafting_altars.objs.toml b/data/skill/runecrafting/runecrafting_altars.objs.toml index 7468f05c9a..36ede3d24e 100644 --- a/data/skill/runecrafting/runecrafting_altars.objs.toml +++ b/data/skill/runecrafting/runecrafting_altars.objs.toml @@ -234,6 +234,10 @@ examine = "A mysterious power emanates from this shrine." id = 2488 examine = "A mysterious power emanates from this shrine." +[astral_altar] +id = 17010 +examine = "A mysterious power emanates from this shrine." + [blood_altar] id = 30624 examine = "A mysterious power emanates from this shrine." diff --git a/data/skill/slayer/chaeldar.enums.toml b/data/skill/slayer/chaeldar.enums.toml index 6894b09e7c..92c2e5af41 100644 --- a/data/skill/slayer/chaeldar.enums.toml +++ b/data/skill/slayer/chaeldar.enums.toml @@ -49,11 +49,11 @@ values = { black_demon = 10, bloodveld = 8, blue_dragon = 8, -# brine_rat = 7, -# cave_horror = 10, + brine_rat = 7, + cave_horror = 10, rock_crab = 8, dagannoth_lighthouse_range_74 = 11, -# dust_devil = 9, + dust_devil = 9, # elf_warrior = 8, # fever_spider = 7, fire_giant = 12, @@ -61,14 +61,14 @@ values = { greater_demon = 9, hellhound = 9, jelly = 10, -# jungle_horror = 10, -# jungle_strykewyrm = 12, -# kalphite_worker = 11, + jungle_horror = 10, + jungle_strykewyrm = 12, + kalphite_worker = 11, kurask = 12, lesser_demon = 9, # zygomite = 7, nechryael = 12, -# shadow_warrior = 8, + shadow_warrior = 8, skeletal_wyvern = 7, spiritual_mage_zamorak = 12, ice_troll_troll_country = 11, diff --git a/data/skill/slayer/duradel.enums.toml b/data/skill/slayer/duradel.enums.toml index 4dcb1e6b5f..21b2882060 100644 --- a/data/skill/slayer/duradel.enums.toml +++ b/data/skill/slayer/duradel.enums.toml @@ -45,25 +45,25 @@ values = { black_dragon = 9, bloodveld = 10, dagannoth_lighthouse_range_74 = 10, -# dark_beast = 15, -# desert_strykewyrm = 11, -# dust_devil = 10, + dark_beast = 15, + desert_strykewyrm = 11, + dust_devil = 10, fire_giant = 10, gargoyle = 10, gorak = 5, greater_demon = 10, hellhound = 9, -# ice_strykewyrm = 8, + ice_strykewyrm = 8, iron_dragon = 9, -# jungle_strykewyrm = 10, -# kalphite_worker = 10, + jungle_strykewyrm = 10, + kalphite_worker = 10, mithril_dragon = 7, nechryael = 10, # giant_scarab_normal = 10, skeletal_wyvern = 5, spiritual_mage_zamorak = 10, steel_dragon = 7, -# suqah = 5, + suqah = 5, # warped_terrorbird = 9, # waterfiend = 10, } diff --git a/data/skill/slayer/kuradal.enums.toml b/data/skill/slayer/kuradal.enums.toml index 0e1eaef0f0..28f53d5285 100644 --- a/data/skill/slayer/kuradal.enums.toml +++ b/data/skill/slayer/kuradal.enums.toml @@ -51,18 +51,18 @@ values = { bloodveld = 10, blue_dragon = 7, dagannoth_lighthouse_range_74 = 10, -# dark_beast = 12, -# desert_strykewyrm = 7, -# dust_devil = 10, + dark_beast = 12, + desert_strykewyrm = 7, + dust_devil = 10, # elf_warrior = 12, fire_giant = 10, gargoyle = 12, greater_demon = 11, hellhound = 10, -# ice_strykewyrm = 9, + ice_strykewyrm = 9, iron_dragon = 9, -# jungle_strykewyrm = 8, -# kalphite_worker = 5, + jungle_strykewyrm = 8, + kalphite_worker = 5, # living_rock_protector = 10, mithril_dragon = 8, nechryael = 10, @@ -70,7 +70,7 @@ values = { skeletal_wyvern = 5, spiritual_mage_zamorak = 10, steel_dragon = 9, -# suqah = 5, + suqah = 5, # terror_dog = 6, # tormented_demon = 8, tzhaar_mej = 7, diff --git a/data/skill/slayer/mazchna.enums.toml b/data/skill/slayer/mazchna.enums.toml index ce24d8de1d..2c4b2e88f3 100644 --- a/data/skill/slayer/mazchna.enums.toml +++ b/data/skill/slayer/mazchna.enums.toml @@ -59,13 +59,13 @@ values = { # killerwatt = 6, lizard = 8, # mogre = 8, - # pyrefiend_large = 8, + pyrefiend_large = 8, rockslug = 8, scorpion = 7, # asyn_shade = 8, skeleton_heavy = 7, # vampyre_juvinate = 6, - # wall_beast = 7, + wall_beast = 7, wolf = 7, zombie = 7, } diff --git a/data/skill/slayer/slayer.enums.toml b/data/skill/slayer/slayer.enums.toml index c1cc4f12e2..9866a8308b 100644 --- a/data/skill/slayer/slayer.enums.toml +++ b/data/skill/slayer/slayer.enums.toml @@ -295,4 +295,11 @@ values = { terror_dog = "haunted_mine", skeletal_wyvern = "elemental_workshop_i", ice_strykewyrm = "the_tale_of_the_muspah", +} + +[slayer_task_variable] +keyType = "npc" +valueType = "string" +values = { + aquanite = "aquanites", } \ No newline at end of file diff --git a/data/skill/slayer/sumona.enums.toml b/data/skill/slayer/sumona.enums.toml index ed98b38af6..d03e7bd9ea 100644 --- a/data/skill/slayer/sumona.enums.toml +++ b/data/skill/slayer/sumona.enums.toml @@ -52,20 +52,20 @@ values = { bloodveld = 10, blue_dragon = 5, cave_crawler = 15, -# cave_horror = 15, + cave_horror = 15, crocodile_kharidian_desert = 4, dagannoth_lighthouse_range_74 = 10, lizard = 4, -# desert_strykewyrm = 14, -# dust_devil = 15, + desert_strykewyrm = 14, + dust_devil = 15, # elf_warrior = 10, fire_giant = 10, # gargoyle = 10, greater_demon = 10, hellhound = 10, iron_dragon = 7, -# jungle_strykewyrm = 12, -# kalphite_worker = 10, + jungle_strykewyrm = 12, + kalphite_worker = 10, kurask = 15, nechryael = 10, red_dragon = 5, diff --git a/data/skill/slayer/turael.enums.toml b/data/skill/slayer/turael.enums.toml index ec0a3a2459..c00be636dd 100644 --- a/data/skill/slayer/turael.enums.toml +++ b/data/skill/slayer/turael.enums.toml @@ -37,7 +37,7 @@ values = { ghost = 7, spider = 6, skeleton_heavy = 7, -# kalphite_worker = 6, + kalphite_worker = 6, lizard = 8, guard_dog = 7, icefiend = 8, diff --git a/data/skill/slayer/vannaka.enums.toml b/data/skill/slayer/vannaka.enums.toml index db32faae86..a2684929a3 100644 --- a/data/skill/slayer/vannaka.enums.toml +++ b/data/skill/slayer/vannaka.enums.toml @@ -57,12 +57,12 @@ values = { basilisk = 8, bloodveld = 8, black_dragon = 7, -# brine_rat = 7, + brine_rat = 7, cockatrice = 8, rock_crab = 7, crocodile_kharidian_desert = 6, dagannoth_lighthouse_range_74 = 7, -# dust_devil = 8, + dust_devil = 8, # elf_warrior = 7, # fever_spider = 7, fire_giant = 7, @@ -76,8 +76,8 @@ values = { ice_warrior = 7, infernal_mage = 8, jelly = 8, -# jungle_horror = 8, -# kalphite_worker = 7, + jungle_horror = 8, + kalphite_worker = 7, kurask = 7, lesser_demon = 7, # mogre = 7, @@ -88,7 +88,7 @@ values = { pyrefiend_large = 8, # sea_snake_young = 6, # asyn_shade = 8, -# shadow_warrior = 8, + shadow_warrior = 8, spiritual_mage_zamorak = 8, ice_troll_troll_country = 7, turoth = 8, diff --git a/engine/src/main/kotlin/world/gregs/voidps/engine/data/definition/AnimationDefinitions.kt b/engine/src/main/kotlin/world/gregs/voidps/engine/data/definition/AnimationDefinitions.kt index 7f5affbfa9..7b67ad637a 100644 --- a/engine/src/main/kotlin/world/gregs/voidps/engine/data/definition/AnimationDefinitions.kt +++ b/engine/src/main/kotlin/world/gregs/voidps/engine/data/definition/AnimationDefinitions.kt @@ -36,6 +36,7 @@ class AnimationDefinitions( } } require(!ids.containsKey(stringId)) { "Duplicate animation id found '$stringId' at $path." } + require(id != -1) { "Missing id for animation '$stringId' at $path." } ids[stringId] = id definitions[id].stringId = stringId if (params.isNotEmpty()) { diff --git a/engine/src/main/kotlin/world/gregs/voidps/engine/entity/character/mode/Wander.kt b/engine/src/main/kotlin/world/gregs/voidps/engine/entity/character/mode/Wander.kt index d26a2c8e01..8b3b38570b 100644 --- a/engine/src/main/kotlin/world/gregs/voidps/engine/entity/character/mode/Wander.kt +++ b/engine/src/main/kotlin/world/gregs/voidps/engine/entity/character/mode/Wander.kt @@ -1,6 +1,7 @@ package world.gregs.voidps.engine.entity.character.mode import world.gregs.voidps.engine.data.Settings +import world.gregs.voidps.engine.data.definition.NPCDefinitions import world.gregs.voidps.engine.entity.character.mode.move.Movement import world.gregs.voidps.engine.entity.character.move.tele import world.gregs.voidps.engine.entity.character.npc.NPC @@ -50,7 +51,9 @@ class Wander( if (!Settings["world.npcs.randomWalk", false]) { return false } - return when (npc.def.walkMode.toInt()) { + val id = npc["transform_id", npc.id] + val def = NPCDefinitions.get(id) + return when (def.walkMode.toInt()) { ModeType.WANDER_THROUGH, ModeType.WANDER_SPECIAL, ModeType.WANDER_WATER -> true else -> false } diff --git a/engine/src/main/kotlin/world/gregs/voidps/engine/entity/character/mode/combat/CombatMovement.kt b/engine/src/main/kotlin/world/gregs/voidps/engine/entity/character/mode/combat/CombatMovement.kt index f4d5fc5b54..78fbd6be65 100644 --- a/engine/src/main/kotlin/world/gregs/voidps/engine/entity/character/mode/combat/CombatMovement.kt +++ b/engine/src/main/kotlin/world/gregs/voidps/engine/entity/character/mode/combat/CombatMovement.kt @@ -49,7 +49,7 @@ class CombatMovement( } if (character is NPC) { val spawn: Tile = character["spawn_tile"] ?: return - val definition = get().get(character.def["combat_def", character.id]) + val definition = get().get(character.transformDef["combat_def", character.id]) if (!withinAggro(this.target, spawn, definition)) { character.mode = EmptyMode return @@ -101,7 +101,14 @@ class CombatMovement( return false } - private fun attackRange(): Int = character["attack_range", if (character is NPC) character.def["attack_range", get().get(character.def["combat_def", character.id]).attackRange] else 1] + private fun attackRange(): Int { + val default = if (character is NPC) { + val def = character.transformDef + val combatDefinition = get().get(def["combat_def", character.id]) + def["attack_range", combatDefinition.attackRange] + } else 1 + return character["attack_range", default] + } override fun onCompletion() { } diff --git a/engine/src/main/kotlin/world/gregs/voidps/engine/entity/character/mode/move/Movement.kt b/engine/src/main/kotlin/world/gregs/voidps/engine/entity/character/mode/move/Movement.kt index 128918b72d..f6e66dc622 100644 --- a/engine/src/main/kotlin/world/gregs/voidps/engine/entity/character/mode/move/Movement.kt +++ b/engine/src/main/kotlin/world/gregs/voidps/engine/entity/character/mode/move/Movement.kt @@ -11,6 +11,7 @@ import world.gregs.voidps.engine.data.definition.Areas import world.gregs.voidps.engine.entity.character.Character import world.gregs.voidps.engine.entity.character.mode.EmptyMode import world.gregs.voidps.engine.entity.character.mode.Mode +import world.gregs.voidps.engine.entity.character.mode.ModeType import world.gregs.voidps.engine.entity.character.mode.move.target.TargetStrategy import world.gregs.voidps.engine.entity.character.move.running import world.gregs.voidps.engine.entity.character.npc.NPC diff --git a/engine/src/main/kotlin/world/gregs/voidps/engine/entity/character/mode/move/target/NPCCharacterTargetStrategy.kt b/engine/src/main/kotlin/world/gregs/voidps/engine/entity/character/mode/move/target/NPCCharacterTargetStrategy.kt index 8949d8f40a..375c165376 100644 --- a/engine/src/main/kotlin/world/gregs/voidps/engine/entity/character/mode/move/target/NPCCharacterTargetStrategy.kt +++ b/engine/src/main/kotlin/world/gregs/voidps/engine/entity/character/mode/move/target/NPCCharacterTargetStrategy.kt @@ -1,7 +1,10 @@ package world.gregs.voidps.engine.entity.character.mode.move.target import org.rsmod.game.pathfinder.PathFinder +import world.gregs.voidps.engine.data.definition.NPCDefinitions import world.gregs.voidps.engine.entity.character.Character +import world.gregs.voidps.engine.entity.character.mode.ModeType +import world.gregs.voidps.engine.entity.character.mode.Wander import world.gregs.voidps.engine.entity.character.npc.NPC import world.gregs.voidps.type.Tile @@ -23,8 +26,15 @@ data class NPCCharacterTargetStrategy( get() = character.size override fun destination(source: Character): Tile { - if (source is NPC && source.id == "bed_draynor") { - return Tile.EMPTY + if (source is NPC) { + val def = if (source.contains("transform_id")) { + NPCDefinitions.get(source["transform_id", source.id]) + } else { + source.def + } + if (def.walkMode.toInt() == ModeType.EMPTY) { + return Tile.EMPTY + } } return Tile( PathFinder.naiveDestination( diff --git a/engine/src/main/kotlin/world/gregs/voidps/engine/entity/character/npc/NPC.kt b/engine/src/main/kotlin/world/gregs/voidps/engine/entity/character/npc/NPC.kt index 72f4e7dcb0..93323731fc 100644 --- a/engine/src/main/kotlin/world/gregs/voidps/engine/entity/character/npc/NPC.kt +++ b/engine/src/main/kotlin/world/gregs/voidps/engine/entity/character/npc/NPC.kt @@ -32,8 +32,21 @@ data class NPC( override val visuals: NPCVisuals = NPCVisuals() var hide = false - override var blockMove: Int = if (def["solid", true]) CollisionFlag.BLOCK_PLAYERS or CollisionFlag.BLOCK_NPCS else 0 - override var collisionFlag: Int = CollisionFlag.BLOCK_NPCS or if (def["solid", false]) CollisionFlag.FLOOR else 0 + override val blockMove: Int + get() = if (transformDef["solid", true]) CollisionFlag.BLOCK_PLAYERS or CollisionFlag.BLOCK_NPCS else 0 + override val collisionFlag: Int + get() = CollisionFlag.BLOCK_NPCS or if (transformDef["solid", false]) CollisionFlag.FLOOR else 0 + + val transformId: String + get() = this["transform_id", id] + + val transformDef: NPCDefinition + get() { + if (contains("transform_id")) { + return NPCDefinitions.get(get("transform_id", id)) + } + return def + } init { if (index != -1) { diff --git a/game/src/main/kotlin/content/area/fremennik_province/lunar_isle/AstralAltar.kt b/game/src/main/kotlin/content/area/fremennik_province/lunar_isle/AstralAltar.kt new file mode 100644 index 0000000000..6e966015d4 --- /dev/null +++ b/game/src/main/kotlin/content/area/fremennik_province/lunar_isle/AstralAltar.kt @@ -0,0 +1,20 @@ +package content.area.fremennik_province.lunar_isle + +import world.gregs.voidps.engine.Script +import world.gregs.voidps.engine.client.message +import world.gregs.voidps.engine.client.ui.open + +class AstralAltar : Script { + init { + objectOperate("Pray", "astral_altar") { + anim("altar_pray") + if (interfaces.contains("lunar_spellbook")) { + open("modern_spellbook") + message("Lunar spells deactivated!") + } else { + open("lunar_spellbook") + message("Lunar spells activated!") + } + } + } +} diff --git a/game/src/main/kotlin/content/area/fremennik_province/lunar_isle/CaptainBentley.kt b/game/src/main/kotlin/content/area/fremennik_province/lunar_isle/CaptainBentley.kt new file mode 100644 index 0000000000..11198d9176 --- /dev/null +++ b/game/src/main/kotlin/content/area/fremennik_province/lunar_isle/CaptainBentley.kt @@ -0,0 +1,49 @@ +package content.area.fremennik_province.lunar_isle + +import content.entity.player.dialogue.Neutral +import content.entity.player.dialogue.type.choice +import content.entity.player.dialogue.type.npc +import content.entity.player.dialogue.type.player +import world.gregs.voidps.engine.Script +import world.gregs.voidps.engine.data.definition.Areas +import world.gregs.voidps.engine.entity.character.jingle +import world.gregs.voidps.engine.entity.character.move.tele + +class CaptainBentley : Script { + init { + playerSpawn { + sendVariable("lunar_diplomacy") + } + + npcOperate("Talk-to", "captain_bentley*") { + if (tile in Areas["lunar_isle"]) { + player("Hi.") + npc("And you're wanting what now?") + choice { + option("Can you take me back to Rellekka please?") { + npc("I'll take you as far as Pirates' Cove. You'll have to find the rest of the way back yourself.") + tele(2224, 3796, 2) + } + option("So we're here?") { + npc("Yep. You're free to explore the island. Be careful though, the Moon Clan are very powerful, it wouldn't be wise to wrong them.") + player("Thanks, I'll keep that seal of passage close.") + } + } + } else { + player("Can we head to Lunar Isle?") + npc("Sure matey!") + // TODO interface 431 + jingle("sailing_theme_short") + tele(2137, 3900, 2) + } + } + + npcOperate("Travel", "captain_bentley*") { + if (tile in Areas["lunar_isle"]) { + tele(2224, 3796, 2) + } else { + tele(2137, 3900, 2) + } + } + } +} diff --git a/game/src/main/kotlin/content/area/fremennik_province/lunar_isle/Oneiromancer.kt b/game/src/main/kotlin/content/area/fremennik_province/lunar_isle/Oneiromancer.kt new file mode 100644 index 0000000000..1f9c3f4b6c --- /dev/null +++ b/game/src/main/kotlin/content/area/fremennik_province/lunar_isle/Oneiromancer.kt @@ -0,0 +1,31 @@ +package content.area.fremennik_province.lunar_isle + +import content.entity.player.dialogue.Neutral +import content.entity.player.dialogue.Quiz +import content.entity.player.dialogue.Sad +import content.entity.player.dialogue.type.choice +import content.entity.player.dialogue.type.npc +import content.entity.player.dialogue.type.player +import world.gregs.voidps.engine.Script + +class Oneiromancer : Script { + init { + npcOperate("Talk-to", "oneiromancer") { + npc("Hello there. What do you want to talk about?") + choice { + option("The state of the island.") { + player("Hi, how are things going?") + npc("Well hopefully a lot better now that you've initiated the calm between the Moon Clan and the Fremenniks. Remember, if you want to use our Lunar Spells at any time, pray at the altar beside me and you can modify") + npc("your knowledge!") + } + option("Cyrisus.") { + player("Hi.") + npc("Hello there. I hear that Cyrisus is no longer with us.") + player("He died fighting for a good cause. He'll be remembered as a great hero.") + npc("I suppose the good do die young.") + } + option("Nothing.") + } + } + } +} diff --git a/game/src/main/kotlin/content/area/fremennik_province/lunar_isle/Suqah.kt b/game/src/main/kotlin/content/area/fremennik_province/lunar_isle/Suqah.kt new file mode 100644 index 0000000000..d895ae7c5c --- /dev/null +++ b/game/src/main/kotlin/content/area/fremennik_province/lunar_isle/Suqah.kt @@ -0,0 +1,14 @@ +package content.area.fremennik_province.lunar_isle + +import content.skill.prayer.protectMagic +import content.skill.prayer.protectMelee +import content.skill.prayer.protectRange +import world.gregs.voidps.engine.Script + +class Suqah : Script { + init { + npcCondition("no_protect_melee") { !it.protectMelee() } + npcCondition("no_protect_magic") { !it.protectMagic() } + npcCondition("no_protect_range") { !it.protectRange() } + } +} diff --git a/game/src/main/kotlin/content/area/fremennik_province/pirates_cove/LokarSearunner.kt b/game/src/main/kotlin/content/area/fremennik_province/pirates_cove/LokarSearunner.kt new file mode 100644 index 0000000000..7ae96d3214 --- /dev/null +++ b/game/src/main/kotlin/content/area/fremennik_province/pirates_cove/LokarSearunner.kt @@ -0,0 +1,56 @@ +package content.area.fremennik_province.pirates_cove + +import content.entity.player.dialogue.Confused +import content.entity.player.dialogue.Happy +import content.entity.player.dialogue.Neutral +import content.entity.player.dialogue.Quiz +import content.entity.player.dialogue.type.choice +import content.entity.player.dialogue.type.npc +import content.entity.player.dialogue.type.player +import world.gregs.voidps.engine.Script +import world.gregs.voidps.engine.data.definition.Areas +import world.gregs.voidps.engine.entity.character.move.tele + +class LokarSearunner : Script { + init { + npcOperate("Talk-to", "lokar_searunner_after") { + if (tile in Areas["pirates_cove"]) { + player("Hello again Lokar.") + val title = "Dalkar Drapare" + npc("Hi again $title! What can I do for you?") + choice { + option("Can you take me back to Rellekka?") { + player("Can you take me back to Rellekka please?") + npc("Hey, if you want to go back to loserville with all the losers, who am I to stop you?") + tele(2621, 3686) + } + option("Nothing thanks.") { + player("Nothing thanks! I just saw you here and thought I'd say hello!") + npc("Hey, I knew you seemed cool when I met you $title!") + } + } + } else { + player("Hi Lokar, can you take me back to your ship?") + npc("Sheesh, make your mind up pal, I'm not a taxi service!") + choice { + option("Go now.") { + tele(2213, 3794) + } + option("Don't go.") { + player("Actually, I've changed my mind. Again. I don't want to go.") + npc("You are possibly the most indecisive person I have ever met...") + player("Well, 'bye then.") + } + } + } + } + + npcOperate("Travel", "lokar_searunner_after") { + if (tile in Areas["pirates_cove"]) { + tele(2621, 3686) + } else { + tele(2213, 3794) + } + } + } +} diff --git a/game/src/main/kotlin/content/area/fremennik_province/rellekka/Erjolf.kt b/game/src/main/kotlin/content/area/fremennik_province/rellekka/Erjolf.kt new file mode 100644 index 0000000000..1e9a20296c --- /dev/null +++ b/game/src/main/kotlin/content/area/fremennik_province/rellekka/Erjolf.kt @@ -0,0 +1,24 @@ +package content.area.fremennik_province.rellekka + +import content.entity.player.dialogue.Angry +import content.entity.player.dialogue.Happy +import content.entity.player.dialogue.Quiz +import content.entity.player.dialogue.Shifty +import content.entity.player.dialogue.type.npc +import content.entity.player.dialogue.type.player +import world.gregs.voidps.engine.Script + +class Erjolf : Script { + init { + npcOperate("Talk-to", "erjolf") { + npc("Incredible! This'll show them!") + player("Hello?") + npc("Oh! Hello there.") + player("You seem rather excited about something.") + npc("Who, me? No, I'm not excited about anything. I certainly haven't found anything amazing inside the caves here.") + player("You won't mind if I have a look inside the cave, then.") + npc("Just you hold on a minute. I know what you adventurers are like, you'll wander in there and decide that anything you find is yours to take.") + // TODO Tale of the Muspah + } + } +} diff --git a/game/src/main/kotlin/content/area/fremennik_province/rellekka/IceStrykewyrm.kt b/game/src/main/kotlin/content/area/fremennik_province/rellekka/IceStrykewyrm.kt new file mode 100644 index 0000000000..874d1fe4a3 --- /dev/null +++ b/game/src/main/kotlin/content/area/fremennik_province/rellekka/IceStrykewyrm.kt @@ -0,0 +1,29 @@ +package content.area.fremennik_province.rellekka + +import content.area.kandarin.feldip_hills.JungleStrykewyrm +import content.entity.combat.hit.directHit +import world.gregs.voidps.engine.Script +import world.gregs.voidps.engine.client.message + +class IceStrykewyrm : Script { + init { + npcOperate("Investigate", "mound_ice_strykewyrm") { (target) -> + JungleStrykewyrm.investigate(this, target, "ice_strykewyrm") + } + + npcAttack("ice_strykewyrm", "dig") { target -> + JungleStrykewyrm.burrow(this, target) + } + + npcCombatDamage("ice_strykewyrm") { + if (it.spell.startsWith("ice_")) { + directHit(it.damage, "healed") + } + } + + objTeleportTakeOff("Enter", "ice_strykewyrm_cave_entrance") { _, _ -> + message("You follow the cave down deeper.") + 0 + } + } +} diff --git a/game/src/main/kotlin/content/area/fremennik_province/rellekka/brine_rat_cavern/BrineRatCavern.kt b/game/src/main/kotlin/content/area/fremennik_province/rellekka/brine_rat_cavern/BrineRatCavern.kt new file mode 100644 index 0000000000..8b6ef6e2a8 --- /dev/null +++ b/game/src/main/kotlin/content/area/fremennik_province/rellekka/brine_rat_cavern/BrineRatCavern.kt @@ -0,0 +1,61 @@ +package content.area.fremennik_province.rellekka.brine_rat_cavern + +import world.gregs.voidps.engine.Script +import world.gregs.voidps.engine.client.message +import world.gregs.voidps.engine.client.ui.open +import world.gregs.voidps.engine.data.definition.Areas +import world.gregs.voidps.engine.entity.character.areaSound +import world.gregs.voidps.engine.entity.character.move.tele +import world.gregs.voidps.engine.entity.character.sound +import world.gregs.voidps.type.Direction +import world.gregs.voidps.type.Tile +import world.gregs.voidps.type.equals + +class BrineRatCavern : Script { + init { + npcOperate("Roll", "olaf_cave_boulder") { (target) -> + if (!target.tile.equals(2691, 10124)) { + return@npcOperate + } + walkToDelay(Tile(2692, 10123)) + message("You push the boulder.") + face(Direction.NORTH) + areaSound("olaf_roll_boulder", tile, radius = 7) + delay(1) + anim("olaf_boulder_push") + delay(1) + target.exactMove(Tile(2691, 10126), startDelay = 20, delay = 75) + exactMoveDelay(Tile(2691, 10125), startDelay = 20, delay = 75, direction = Direction.NORTH) + delay(3) + clearAnim() + face(Direction.NORTH) + delay(5) + tele(2691, 10125) + } + + objTeleportTakeOff("Exit", "brine_rat_cavern_exit*") { _, _ -> + message("You squeeze through the narrow crack in the cliff face.") + 1 + } + + objTeleportLand("Exit", "brine_rat_cavern_exit*") { _, _ -> + message("You exit the cave. From this side you can't even make out how to get into the cave!") + message("You'll likely need to dig to get back inside.") + } + + itemOption("Dig", "spade") { + if (tile !in Areas["brine_rat_cavern_entrance"]) { + return@itemOption + } + message("You dig a hole...") + open("fade_out") + delay(4) + tele(2697, 10120) + delay(1) + message("...and fall into a dark and slimy pit!") + gfx("stun_long", delay = 20) + open("fade_in") + sound("olaf_fall_into_cave") + } + } +} diff --git a/game/src/main/kotlin/content/area/kandarin/feldip_hills/JungleStrykewyrm.kt b/game/src/main/kotlin/content/area/kandarin/feldip_hills/JungleStrykewyrm.kt new file mode 100644 index 0000000000..e75a58e81d --- /dev/null +++ b/game/src/main/kotlin/content/area/kandarin/feldip_hills/JungleStrykewyrm.kt @@ -0,0 +1,99 @@ +package content.area.kandarin.feldip_hills + +import content.entity.combat.hit.directHit +import content.entity.combat.inCombat +import content.entity.effect.clearTransform +import content.entity.effect.toxin.poison +import content.entity.effect.transform +import content.skill.slayer.slayerTask +import world.gregs.voidps.engine.Script +import world.gregs.voidps.engine.client.instruction.handle.interactPlayer +import world.gregs.voidps.engine.client.message +import world.gregs.voidps.engine.client.variable.start +import world.gregs.voidps.engine.data.Settings +import world.gregs.voidps.engine.entity.character.Character +import world.gregs.voidps.engine.entity.character.mode.EmptyMode +import world.gregs.voidps.engine.entity.character.mode.PauseMode +import world.gregs.voidps.engine.entity.character.npc.NPC +import world.gregs.voidps.engine.entity.character.player.Player +import world.gregs.voidps.engine.queue.softQueue +import world.gregs.voidps.engine.timer.Timer +import world.gregs.voidps.engine.timer.toTicks +import world.gregs.voidps.type.random +import java.util.concurrent.TimeUnit +import kotlin.random.nextInt + +class JungleStrykewyrm : Script { + init { + npcOperate("Investigate", "mound_feldip_hills") { (target) -> + investigate(this, target, "jungle_strykewyrm") + } + + npcTimerStart("strykewyrm_revert") { 20 } + + npcTimerTick("strykewyrm_revert") { + if (inCombat) { + return@npcTimerTick Timer.CONTINUE + } + anim("strykewyrm_bury") + softQueue("bury", 3) { + clearTransform() + } + Timer.CANCEL + } + + npcAttack("jungle_strykewyrm", "dig") { target -> + burrow(this, target) { + poison(target, 88) + } + } + } + companion object { + + fun burrow(source: NPC, target: Character, block: () -> Unit = {}) { + source.anim("strykewyrm_bury") + val temp = source.mode + val type = source.transform + source.start("action_delay", 8) + source.softQueue("burrow", 3) { + source.clearTransform() + source.mode = PauseMode + target.mode = EmptyMode + source.start("action_delay", Int.MAX_VALUE) + source.walkToDelay(target.tile) + source.start("action_delay", 4) + source.mode = temp + source.transform(type) + source.anim("strykewyrm_surface") + if (source.tile.toCuboid(source.size, source.size).contains(target.tile)) { + target.directHit(random.nextInt(50..300)) + block.invoke() + } + } + } + + fun investigate(source: Player, target: NPC, to: String) { + if (Settings["slayer.strykewyrmReqTask", false] && source.slayerTask != to) { + source.anim("emote_stomp") + source.softQueue("stomp_mound", 3) { + source.anim("emote_think") + } + source.message("You need to have strykewyrm assigned as a task in order to fight them.") + return + } + source.anim("emote_stomp") + target.start("movement_delay", Int.MAX_VALUE) + target.mode = EmptyMode + target.steps.clear() + target.softTimers.start("strykewyrm_revert") + target.softQueue("strykewyrm_transform", 3) { + target.mode = EmptyMode + target.transform(to) + target.anim("strykewyrm_surface") + target.face(source) + target.start("action_delay", TimeUnit.SECONDS.toTicks(3)) + target.interactPlayer(source, "Attack") + } + } + } +} diff --git a/game/src/main/kotlin/content/area/kharidian_desert/DesertHeat.kt b/game/src/main/kotlin/content/area/kharidian_desert/DesertHeat.kt new file mode 100644 index 0000000000..07b4384476 --- /dev/null +++ b/game/src/main/kotlin/content/area/kharidian_desert/DesertHeat.kt @@ -0,0 +1,103 @@ +package content.area.kharidian_desert + +import content.entity.combat.hit.directHit +import world.gregs.voidps.engine.Script +import world.gregs.voidps.engine.client.message +import world.gregs.voidps.engine.data.Settings +import world.gregs.voidps.engine.data.definition.EnumDefinitions +import world.gregs.voidps.engine.entity.character.player.Player +import world.gregs.voidps.engine.entity.character.player.chat.ChatType +import world.gregs.voidps.engine.entity.character.player.equip.equipped +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.sound +import world.gregs.voidps.engine.entity.obj.replace +import world.gregs.voidps.engine.inv.inventory +import world.gregs.voidps.engine.inv.remove +import world.gregs.voidps.engine.inv.replace +import world.gregs.voidps.network.login.protocol.visual.update.player.EquipSlot +import world.gregs.voidps.type.random + +class DesertHeat : Script { + init { + entered("kharidian_desert") { + if (!Settings["world.desertHeat", true]) { + return@entered + } + // Doesn't tick when dialogues are open + timers.start("desert_heat") + } + + exited("kharidian_desert") { + timers.stop("desert_heat") + } + + timerStart("desert_heat") { + heatTime(this) + } + + timerTick("desert_heat") { + val index = inventory.items.indexOfFirst { it.id == "waterskin_1" || it.id == "waterskin_2" || it.id == "waterskin_3" || it.id == "waterskin_4" } + if (index != -1) { + val number = inventory[index].id.substringAfterLast("_").toInt() + if (inventory.replace(index, "waterskin_$number", "waterskin_${number - 1}")) { + anim("eat_drink") + sound("drink") + message("You take a drink of water.") + } + } else if (inventory.remove("choc_ice")) { + anim("eat_drink") + message("You eat a choc ice.") + } else if (inventory.contains("waterskin_0")) { + directHit(random.nextInt(1, 11) * 10) + message("Perhaps you should fill up one of your empty waterskins.") + message("You start dying of thirst while you're in the desert.", type = ChatType.Filter) + } else { + directHit(random.nextInt(1, 11) * 10) + message("You should get a waterskin for any travelling in the desert.") + message("You start dying of thirst while you're in the desert.", type = ChatType.Filter) + } + heatTime(this) + } + + objectOperate("Cut", "desert_cactus_full") { (target) -> + if (!inventory.contains("knife")) { + message("You need a knife to cut the cactus...") + return@objectOperate + } + anim("knife_chop") + sound("sword_slash") + target.replace("desert_cactus_empty", ticks = 100) + if (random.nextInt(10) == 0) { + message("You fail to cut the cactus correctly and it gives no water this time.") + return@objectOperate + } + if (!inventory.replace("waterskin_0", "waterkin_1") && !inventory.replace("waterskin_1", "waterkin_2") && !inventory.replace("waterskin_2", "waterkin_3") && !inventory.replace("waterskin_3", "waterkin_4")) { + message("You fail to cut the cactus correctly and it gives no water this time.") + return@objectOperate + } + sound("drink") + exp(Skill.Woodcutting, 10.0) + message("You top up your skin with water from the cactus.") + } + } + + fun heatTime(player: Player): Int { + var time = 150 + time += delay(player, EquipSlot.Hat, -10) + time += delay(player, EquipSlot.Chest, -40) + time += delay(player, EquipSlot.Hands, -10) + time += delay(player, EquipSlot.Legs, -30) + time += delay(player, EquipSlot.Shield, -10) + time += delay(player, EquipSlot.Feet, -10) + return time + } + + private fun delay(player: Player, slot: EquipSlot, default: Int): Int { + val item = player.equipped(slot).id + if (item == "") { + return 0 + } + return EnumDefinitions.intOrNull("desert_heat_delay", item) ?: default + } +} diff --git a/game/src/main/kotlin/content/area/kharidian_desert/al_kharid/DesertStrykewyrm.kt b/game/src/main/kotlin/content/area/kharidian_desert/al_kharid/DesertStrykewyrm.kt new file mode 100644 index 0000000000..baefb72a02 --- /dev/null +++ b/game/src/main/kotlin/content/area/kharidian_desert/al_kharid/DesertStrykewyrm.kt @@ -0,0 +1,16 @@ +package content.area.kharidian_desert.al_kharid + +import content.area.kandarin.feldip_hills.JungleStrykewyrm +import world.gregs.voidps.engine.Script + +class DesertStrykewyrm : Script { + init { + npcOperate("Investigate", "mound_desert_strykewyrm") { (target) -> + JungleStrykewyrm.investigate(this, target, "desert_strykewyrm") + } + + npcAttack("desert_strykewyrm", "dig") { target -> + JungleStrykewyrm.burrow(this, target) + } + } +} diff --git a/game/src/main/kotlin/content/area/kharidian_desert/pollnivneach/smoke_dungeon/DustDevil.kt b/game/src/main/kotlin/content/area/kharidian_desert/pollnivneach/smoke_dungeon/DustDevil.kt new file mode 100644 index 0000000000..c7c215a2af --- /dev/null +++ b/game/src/main/kotlin/content/area/kharidian_desert/pollnivneach/smoke_dungeon/DustDevil.kt @@ -0,0 +1,14 @@ +package content.area.kharidian_desert.pollnivneach.smoke_dungeon + +import content.entity.player.equip.Equipment +import world.gregs.voidps.engine.Script +import world.gregs.voidps.engine.entity.character.player.Player +import world.gregs.voidps.engine.entity.character.player.equip.equipped +import world.gregs.voidps.network.login.protocol.visual.update.player.EquipSlot + +class DustDevil : Script { + init { + npcCondition("face_mask") { it is Player && Equipment.isFaceMask(it.equipped(EquipSlot.Hat).id) } + npcCondition("no_face_mask") { it is Player && !Equipment.isFaceMask(it.equipped(EquipSlot.Hat).id) } + } +} diff --git a/game/src/main/kotlin/content/area/kharidian_desert/pollnivneach/smoke_dungeon/SmokeDungeon.kt b/game/src/main/kotlin/content/area/kharidian_desert/pollnivneach/smoke_dungeon/SmokeDungeon.kt new file mode 100644 index 0000000000..b2aaf5c826 --- /dev/null +++ b/game/src/main/kotlin/content/area/kharidian_desert/pollnivneach/smoke_dungeon/SmokeDungeon.kt @@ -0,0 +1,11 @@ +package content.area.kharidian_desert.pollnivneach.smoke_dungeon + +import world.gregs.voidps.engine.Script + +class SmokeDungeon : Script { + init { + // TODO smoke interface - https://youtu.be/2ARmHyBkO8w?t=108 +// entered("smoke_dungeon") {} +// exited("smoke_dungeon") {} + } +} diff --git a/game/src/main/kotlin/content/area/misthalin/lumbridge/swamp/LumbridgeSwamp.kt b/game/src/main/kotlin/content/area/misthalin/lumbridge/swamp/LumbridgeSwamp.kt index 0ff9b17e06..d2fdf99093 100644 --- a/game/src/main/kotlin/content/area/misthalin/lumbridge/swamp/LumbridgeSwamp.kt +++ b/game/src/main/kotlin/content/area/misthalin/lumbridge/swamp/LumbridgeSwamp.kt @@ -1,5 +1,6 @@ package content.area.misthalin.lumbridge.swamp +import content.entity.combat.hit.hit import content.entity.player.bank.ownsItem import content.entity.player.dialogue.type.choice import content.entity.player.dialogue.type.item @@ -116,11 +117,6 @@ class LumbridgeSwamp : Script { } anim("climb_down") delay(2) - if (light) { - open("level_one_darkness") - } else { - open("level_three_darkness") - } tele(3167, 9573) } else if (inventory.contains("rope")) { choice("Attach a rope to the top of the hole?") { @@ -140,7 +136,32 @@ class LumbridgeSwamp : Script { } } - objTeleportLand("Climb", "swamp_cave_climbing_rope") { _, _ -> + entered("lumbridge_swamp_caves") { + if (Light.hasLightSource(this)) { + open("level_one_darkness") + } else { + open("level_three_darkness") + timers.start("insect_swarm") + } + } + + timerStart("insect_swarm") { + message("Tiny biting insects swarm all over you!") + sound("insect_swarm") + 10 + } + + timerTick("insect_swarm") { + hit(this, damage = 10) + sound("insect_bites") + 1 + } + + interfaceClosed("level_three_darkness") { + timers.stop("insect_swarm") + } + + exited("lumbridge_swamp_caves") { close("level_one_darkness") close("level_three_darkness") } diff --git a/game/src/main/kotlin/content/area/misthalin/lumbridge/swamp/WallBeast.kt b/game/src/main/kotlin/content/area/misthalin/lumbridge/swamp/WallBeast.kt new file mode 100644 index 0000000000..b602b42e2a --- /dev/null +++ b/game/src/main/kotlin/content/area/misthalin/lumbridge/swamp/WallBeast.kt @@ -0,0 +1,98 @@ +package content.area.misthalin.lumbridge.swamp + +import content.entity.combat.hit.directHit +import content.entity.combat.target +import content.entity.combat.underAttack +import content.entity.effect.clearTransform +import content.entity.effect.transform +import world.gregs.voidps.engine.Script +import world.gregs.voidps.engine.client.instruction.handle.interactPlayer +import world.gregs.voidps.engine.client.message +import world.gregs.voidps.engine.data.definition.AreaDefinition +import world.gregs.voidps.engine.entity.character.mode.EmptyMode +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.Player +import world.gregs.voidps.engine.entity.character.player.equip.equipped +import world.gregs.voidps.engine.entity.character.sound +import world.gregs.voidps.engine.queue.strongQueue +import world.gregs.voidps.engine.timer.Timer +import world.gregs.voidps.engine.timer.toTicks +import world.gregs.voidps.network.login.protocol.visual.update.player.EquipSlot +import world.gregs.voidps.type.Direction +import world.gregs.voidps.type.random +import java.util.concurrent.TimeUnit + +class WallBeast : Script { + init { + entered("wall_beast_spot_1", ::grab) + entered("wall_beast_spot_2", ::grab) + entered("wall_beast_spot_3", ::grab) + entered("wall_beast_spot_4", ::grab) + entered("wall_beast_spot_5", ::grab) + entered("wall_beast_spot_6", ::grab) + entered("wall_beast_spot_7", ::grab) + + npcTimerStart("wall_beast_revert") { + TimeUnit.SECONDS.toTicks(8) // TODO this is triggered on combat stop not a timer + } + + npcTimerTick("wall_beast_revert") { + if (underAttack) { // FIXME should be: attacking but doesn't check if swinging or not + return@npcTimerTick Timer.CONTINUE + } + clearTransform() + mode = EmptyMode + Timer.CANCEL + } + } + + fun grab(player: Player, definition: AreaDefinition) { + if (random.nextInt(4) != 0) { + return + } + val tile = definition.area.random() + val beast = NPCs.find(tile.addY(1), "hole_in_the_wall") + if (beast.transform == "wall_beast") { + return + } + if (beast.softTimers.contains("wall_beast_revert")) { + return + } + if (beast.target != null) { + return + } + if (beast.queue.contains("grab_player")) { + return + } + player.steps.clear() + player.strongQueue("grab_player", 2) { + player.tele(tile) + player.face(Direction.NORTH) + beast["movement_delay"] = Int.MAX_VALUE + if (player.equipped(EquipSlot.Hat).id == "spiny_helmet") { + player.message("Your helmet repels the wall beast!") + beast.anim("wall_beast_repelled_attack") + player.sound("wall_beast_foiled") + beast.transform("wall_beast") + pause(4) + beast.interactPlayer(player, "Attack") + beast.softTimers.start("wall_beast_revert") + return@strongQueue + } + player.message("A giant hand appears and grabs your head!") + player.anim("grabbed_by_wall_beast") + player.sound("wall_beast_attack") + beast.anim("wall_beast_attack") + pause(1) + player.anim("held_by_wall_beast") + beast.anim("wall_beast_hold") + pause(8) + beast.anim("released_by_wall_beast") + player.anim("wall_beast_release") + player.sound("male_defend_0") + player.directHit(160, source = beast) + beast.softTimers.start("wall_beast_revert") + } + } +} diff --git a/game/src/main/kotlin/content/area/morytania/mos_le_harmless/CaveyDavey.kt b/game/src/main/kotlin/content/area/morytania/mos_le_harmless/CaveyDavey.kt new file mode 100644 index 0000000000..f2b2ddc558 --- /dev/null +++ b/game/src/main/kotlin/content/area/morytania/mos_le_harmless/CaveyDavey.kt @@ -0,0 +1,83 @@ +package content.area.morytania.mos_le_harmless + +import content.entity.player.dialogue.* +import content.entity.player.dialogue.type.npc +import content.entity.player.dialogue.type.player +import world.gregs.voidps.engine.Script +import world.gregs.voidps.engine.entity.character.player.equip.equipped +import world.gregs.voidps.engine.inv.inventory +import world.gregs.voidps.network.login.protocol.visual.update.player.EquipSlot +import world.gregs.voidps.type.random + +class CaveyDavey : Script { + init { + npcOperate("Talk-to", "cavey_davey") { + if (equipped(EquipSlot.Amulet).id == "witchwood_icon") { + npc("Be ye here te deal with the Horrors?") + player("I might well give it a shot.") + npc("Aye, well, keep yer Icon with ye if ye wants te walk out alive again.") + player("Don't worry, I will.") + } else if (inventory.contains("witchwood_icon")) { + npc("Be ye some form of simpleton? Do ye not hear the howlin' of the Horrors?") + player("Well, I can hear something now you mention it...") + npc("That be them, howlin', always howlin'!") + npc("If ye value yer limbs ye'll put that Icon round yer neck, and hope they don't come out into the light!") + player("Err, all right, I'll get right on that.") + } else { + npc("Be ye mad? There be Horrors in this cave!") + player("What do you mean?") + npc("Have ye ever heard of the sort of evil, flesh-eatin' horrors that dwell in the darkest pits of the world?") + npc("The sort of dark, sanity-breakin' THINGS that cause the livin' to drop to their knees and weep for the fate of all creation?") + npc("Well, have ye?") + player("Yes, I think I've killed a few of them as well.") + npc("Well, that's ok then.") + npc("But, ye'll need a Witchwood Icon from a slayer master if ye want te go in these caves and live.") + player("Why?") + npc("Well, ye see them Jungle Horrors? Well down in the caves there be Cave Horrors.") + npc("They are bigger, badder, meaner, and have a howl that freezes the blood in yer veins.") + npc("Wearin' earmuffs or a helmet won't work, cos them masks they wear make the sound magical. Only thing that works is wearin' a Witchwood Icon.") + npc("That is, o'course, if ye can see them, cos if ye don't have any light down there then yer likely te be picked te bones by the insects before the Horrors get ye.") + player("I see, thanks for the warning.") + npc("Yer welcome.") + } + } + + npcOperate("Talk-to", "monkey_mos_le_harmless") { + if (equipped(EquipSlot.Amulet).id == "monkeyspeak_amulet") { + npc("Eeekeek ookeek!") + return@npcOperate + } + when (random.nextInt(4)) { + 0 -> { + npc("Arr!") + player("Arr!") + npc("Arr!") + player("Arr!") + npc("Arr!") + player("Arr!") + npc("Arr!") + player("Arr!") + npc("Bored now...") + } + 1 -> { + npc("Let me go, can't ye hear them? Howlin' in the dark...") + player("What do you mean?") + npc("I'm not hangin' around te be killed!") + npc("The Horrors, the Horrors!") + } + 2 -> npc("I'm not goin' back in that brewery, not fer all the Bitternuts I can carry!") + 3 -> { + npc("Arr! Yer messin with me monkey plunder!") + player("What?") + } + else -> { + npc("Are ye here for...the stuff?") + player("What?") + npc("You know...the 'special' bananas?") + player("No...why do you ask?") + npc("No reason. Have a nice day.") + } + } + } + } +} diff --git a/game/src/main/kotlin/content/area/morytania/mos_le_harmless/MosLeHarmlessCave.kt b/game/src/main/kotlin/content/area/morytania/mos_le_harmless/MosLeHarmlessCave.kt new file mode 100644 index 0000000000..8ba8933720 --- /dev/null +++ b/game/src/main/kotlin/content/area/morytania/mos_le_harmless/MosLeHarmlessCave.kt @@ -0,0 +1,42 @@ +package content.area.morytania.mos_le_harmless + +import content.entity.player.dialogue.type.choice +import content.skill.firemaking.Light +import world.gregs.voidps.engine.Script +import world.gregs.voidps.engine.client.ui.close +import world.gregs.voidps.engine.client.ui.open +import world.gregs.voidps.engine.entity.character.move.tele +import world.gregs.voidps.engine.entity.character.player.Player +import world.gregs.voidps.engine.entity.character.player.equip.equipped +import world.gregs.voidps.network.login.protocol.visual.update.player.EquipSlot + +class MosLeHarmlessCave : Script { + init { + objectOperate("Enter", "cave_entrance_mos_le_harmless") { + choice("Do you still want to proceed?") { + option("Yes, I think I am fully prepared.") { + open("fade_in") + tele(3748, 9373) + } + option("No, I think I need to go get food, weapons and a light source.") + } + } + + npcCondition("witchwood_icon") { target -> target is Player && target.equipped(EquipSlot.Amulet).id == "witchwood_icon" } + npcCondition("no_witchwood_icon") { target -> target is Player && target.equipped(EquipSlot.Amulet).id != "witchwood_icon" } + + entered("mos_le_harmless_cave") { + if (Light.hasLightSource(this)) { + open("level_one_darkness") + } else { + open("level_three_darkness") + timers.start("insect_swarm") + } + } + + exited("mos_le_harmless_cave") { + close("level_one_darkness") + close("level_three_darkness") + } + } +} diff --git a/game/src/main/kotlin/content/entity/combat/Combat.kt b/game/src/main/kotlin/content/entity/combat/Combat.kt index bd61085857..382bef5889 100644 --- a/game/src/main/kotlin/content/entity/combat/Combat.kt +++ b/game/src/main/kotlin/content/entity/combat/Combat.kt @@ -115,7 +115,7 @@ class Combat(val combatDefinitions: CombatDefinitions) : * [CombatMovement.combatReached] is emitted by [CombatMovement] every tick the [Character] is within range of the target */ fun retaliates(character: Character) = if (character is NPC) { - character.def["retaliates", true] + character.transformDef["retaliates", true] } else { character["auto_retaliate", false] } @@ -132,7 +132,7 @@ class Combat(val combatDefinitions: CombatDefinitions) : } if (character is NPC) { // Retreat - val definition = combatDefinitions.getOrNull(character.def["combat_def", character.id]) ?: return + val definition = combatDefinitions.getOrNull(character.transformDef["combat_def", character.id]) ?: return val spawn: Tile = character["spawn_tile"]!! if (!CombatMovement.withinAggro(source, spawn, definition)) { if (character.mode !is Retreat || (character.mode as Retreat).target != source) { diff --git a/game/src/main/kotlin/content/entity/combat/Target.kt b/game/src/main/kotlin/content/entity/combat/Target.kt index 84b63bd60d..e604945797 100644 --- a/game/src/main/kotlin/content/entity/combat/Target.kt +++ b/game/src/main/kotlin/content/entity/combat/Target.kt @@ -10,6 +10,7 @@ import content.entity.player.equip.Equipment import content.skill.melee.weapon.fightStyle import content.skill.ranged.ammo import content.skill.slayer.categories +import content.skill.slayer.slayerTask import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap import it.unimi.dsi.fastutil.objects.ObjectArrayList import world.gregs.voidps.engine.client.message @@ -34,6 +35,14 @@ object Target { if (target.id.startsWith("door_support") && NPCDefinitions.get(target.id).options[1] == "Destroy") { return true } + if (target.id == "mound_feldip_hills" && source is Player && source.slayerTask != "jungle_strykewyrm") { + source.message("You need to have strykewyrm assigned as a task in order to fight them.") + return false + } + if (target.id == "mound_desert_strykewyrm" && source is Player && source.slayerTask != "desert_strykewyrm") { + source.message("You need to have strykewyrm assigned as a task in order to fight them.") + return false + } if (target.transform != "") { if (NPCDefinitions.get(target.transform).options[1] != "Attack") { return false diff --git a/game/src/main/kotlin/content/entity/death/NPCDeath.kt b/game/src/main/kotlin/content/entity/death/NPCDeath.kt index 0bf2753eca..d7c23e0348 100644 --- a/game/src/main/kotlin/content/entity/death/NPCDeath.kt +++ b/game/src/main/kotlin/content/entity/death/NPCDeath.kt @@ -14,7 +14,6 @@ import world.gregs.voidps.engine.Script import world.gregs.voidps.engine.client.message import world.gregs.voidps.engine.client.ui.chat.plural import world.gregs.voidps.engine.data.definition.CombatDefinitions -import world.gregs.voidps.engine.data.definition.NPCDefinitions import world.gregs.voidps.engine.entity.Spawn import world.gregs.voidps.engine.entity.World import world.gregs.voidps.engine.entity.character.Character @@ -58,11 +57,9 @@ class NPCDeath( val npc = this strongQueue(name = "death", 1) { val killer = killer - val tile = tile + val tile = if (transformId == "wall_beast") tile.addY(-1) else tile npc["death_tile"] = tile - val id = get("transform_id", npc.id) - val def = NPCDefinitions.get(id) - val combat = combatDefinitions.get(def["combat_def", get("transform_id", npc.id)]) + val combat = combatDefinitions.get(transformDef["combat_def", transformId]) val ticks = anim(combat.deathAnim) if (combat.deathSound != null) { (killer as? Player)?.sound(combat.deathSound!!.id) diff --git a/game/src/main/kotlin/content/entity/obj/ship/CharterShip.kt b/game/src/main/kotlin/content/entity/obj/ship/CharterShip.kt index e4a61b540a..c6ab30017a 100644 --- a/game/src/main/kotlin/content/entity/obj/ship/CharterShip.kt +++ b/game/src/main/kotlin/content/entity/obj/ship/CharterShip.kt @@ -9,6 +9,7 @@ import net.pearx.kasechange.toTitleCase import world.gregs.voidps.engine.Script import world.gregs.voidps.engine.client.message import world.gregs.voidps.engine.client.ui.chat.toDigitGroupString +import world.gregs.voidps.engine.client.ui.closeMenu import world.gregs.voidps.engine.client.ui.open import world.gregs.voidps.engine.entity.character.jingle import world.gregs.voidps.engine.entity.character.move.tele @@ -17,7 +18,7 @@ import world.gregs.voidps.engine.entity.character.player.Player import world.gregs.voidps.engine.entity.character.player.chat.ChatType import world.gregs.voidps.engine.inv.inventory import world.gregs.voidps.engine.inv.remove -import world.gregs.voidps.engine.queue.strongQueue +import world.gregs.voidps.engine.queue.queue import world.gregs.voidps.type.Tile class CharterShip(val ships: CharterShips, val teles: ObjectTeleports) : Script { @@ -99,12 +100,13 @@ class CharterShip(val ships: CharterShips, val teles: ObjectTeleports) : Script if (component == currentLocation) { return@interfaceOption } + closeMenu() val price = ships.get(currentLocation, component) ?: return@interfaceOption if (!hasQuestRequirements(component)) { return@interfaceOption } val readablePrice = price.toDigitGroupString() - strongQueue("charter_ship") { + queue("charter_ship") { if (!inventory.contains("coins", price)) { choice("Sailing to ${component.toTitleCase()} costs $readablePrice coins.") { option("Choose again") { @@ -112,7 +114,7 @@ class CharterShip(val ships: CharterShips, val teles: ObjectTeleports) : Script } option("No") } - return@strongQueue + return@queue } statement("To sail to ${component.toTitleCase()} from here will cost you $readablePrice gold. Are you sure you want to pay that?") choice { diff --git a/game/src/main/kotlin/content/entity/player/combat/Attack.kt b/game/src/main/kotlin/content/entity/player/combat/Attack.kt index 90b3797267..30e122eb75 100644 --- a/game/src/main/kotlin/content/entity/player/combat/Attack.kt +++ b/game/src/main/kotlin/content/entity/player/combat/Attack.kt @@ -28,6 +28,10 @@ class Attack : Script { message("You need a higher slayer level to know how to wound this monster.") return@npcApproach } + if (timers.contains("insect_swarm")) { + message("You can't see to attack anything!") + return@npcApproach + } if (equipped(EquipSlot.Weapon).id.endsWith("_greegree")) { statement("You cannot attack as a monkey.") return@npcApproach diff --git a/game/src/main/kotlin/content/entity/player/command/PlayerCommands.kt b/game/src/main/kotlin/content/entity/player/command/PlayerCommands.kt index 48b07ef029..28aed4df3e 100644 --- a/game/src/main/kotlin/content/entity/player/command/PlayerCommands.kt +++ b/game/src/main/kotlin/content/entity/player/command/PlayerCommands.kt @@ -322,6 +322,7 @@ class PlayerCommands( target[quest] = "completed" } target["recipe_for_disaster"] = "completed" + target["lunar_diplomacy"] = "completed" target["quest_points"] = target["quest_points_total", 1] target.refreshQuestJournal() target.message("All quests unlocked.") diff --git a/game/src/main/kotlin/content/entity/player/equip/Equipment.kt b/game/src/main/kotlin/content/entity/player/equip/Equipment.kt index 9ce124be04..103120d18a 100644 --- a/game/src/main/kotlin/content/entity/player/equip/Equipment.kt +++ b/game/src/main/kotlin/content/entity/player/equip/Equipment.kt @@ -1,6 +1,7 @@ package content.entity.player.equip import content.entity.combat.hit.Hit +import content.entity.effect.transform import content.entity.player.effect.antifire import content.entity.player.effect.superAntifire import content.skill.magic.spell.spell @@ -92,7 +93,7 @@ object Equipment { if (source.tile in area && target.tile in area) { damage = (damage * 1.04).toInt() } - } else if (type == "magic" && target is NPC && target.id == "ice_strykewyrm") { + } else if (type == "magic" && target is NPC && target.transform == "ice_strykewyrm") { val fireCape = source.equipped(EquipSlot.Cape).id == "fire_cape" if (fireCape) { damage += 40 @@ -110,6 +111,8 @@ object Equipment { fun isNosePeg(hat: String) = hat == "nose_peg" || hat.startsWith("slayer_helmet") || hat.startsWith("full_slayer_helmet") + fun isFaceMask(hat: String) = hat == "face_mask" || hat.startsWith("slayer_helmet") || hat.startsWith("full_slayer_helmet") + fun dragonFireImmune(target: Character) = target.protectMagic() || antiDragonShield(target) || target.antifire || target.superAntifire fun antiDragonShield(target: Character): Boolean { diff --git a/game/src/main/kotlin/content/skill/agility/shortcut/Stiles.kt b/game/src/main/kotlin/content/skill/agility/shortcut/Stiles.kt index c9cb3c65f4..055fdccf98 100644 --- a/game/src/main/kotlin/content/skill/agility/shortcut/Stiles.kt +++ b/game/src/main/kotlin/content/skill/agility/shortcut/Stiles.kt @@ -33,6 +33,10 @@ class Stiles : Script { climbStile(target, Direction.EAST) } + objectOperate("Climb-over", "al_kharid_stile") { (target) -> + climbStile(target, Direction.EAST) + } + objectOperate("Climb-over", "falador_farm_stile") { (target) -> val rotation = when (target.rotation) { 2 -> Direction.NORTH diff --git a/game/src/main/kotlin/content/skill/melee/weapon/Weapon.kt b/game/src/main/kotlin/content/skill/melee/weapon/Weapon.kt index 23363d5f56..3dadd30bdb 100644 --- a/game/src/main/kotlin/content/skill/melee/weapon/Weapon.kt +++ b/game/src/main/kotlin/content/skill/melee/weapon/Weapon.kt @@ -249,7 +249,15 @@ val Character.attackSpeed: Int } var Character.attackRange: Int - get() = get("attack_range", if (this is NPC) def["attack_range", get().get(def["combat_def", id]).attackRange] else 1) + get() { + val default = if (this is NPC) { + val combatDefinition = get().get(transformDef["combat_def", id]) + transformDef["attack_range", combatDefinition.attackRange] + } else { + 1 + } + return get("attack_range", default) + } set(value) = set("attack_range", value) // E.g "accurate" diff --git a/game/src/main/kotlin/content/skill/runecrafting/Runecrafting.kt b/game/src/main/kotlin/content/skill/runecrafting/Runecrafting.kt index 94d20bea92..24f4da9fee 100644 --- a/game/src/main/kotlin/content/skill/runecrafting/Runecrafting.kt +++ b/game/src/main/kotlin/content/skill/runecrafting/Runecrafting.kt @@ -102,7 +102,7 @@ class Runecrafting : Script { } } - fun Runecrafting.bindRunes(player: Player, id: String) { + fun bindRunes(player: Player, id: String) { val xp = EnumDefinitions.intOrNull("runecrafting_xp", id) ?: return val level = EnumDefinitions.int("runecrafting_level", id) if (!player.has(Skill.Runecrafting, level, message = true)) { diff --git a/game/src/main/kotlin/content/skill/slayer/Slayer.kt b/game/src/main/kotlin/content/skill/slayer/Slayer.kt index f37dbf62c5..99e0532a84 100644 --- a/game/src/main/kotlin/content/skill/slayer/Slayer.kt +++ b/game/src/main/kotlin/content/skill/slayer/Slayer.kt @@ -105,6 +105,10 @@ private fun hasRequirements(player: Player, index: Int): Boolean { if (player.combatLevel < combatLevel) { return false } + val variable = EnumDefinitions.stringOrNull("slayer_task_variable", index) + if (variable != null && !player.contains(variable)) { + return false + } val quest = EnumDefinitions.stringOrNull("slayer_task_quest", index) ?: return true return player.questCompleted(quest) } diff --git a/game/src/main/resources/game.properties b/game/src/main/resources/game.properties index 55be019604..57207fd37f 100644 --- a/game/src/main/resources/game.properties +++ b/game/src/main/resources/game.properties @@ -115,6 +115,9 @@ world.objs.redberry.regrowTicks=200 # Number of times a player can close a door before it gets stuck world.objs.door.stuck.count=5 +# Whether you can get dehydrated and take damage when in the desert +world.desertHeat=true + #=================================== # Gameplay Mechanics @@ -163,8 +166,15 @@ farming.weeds.regrow=true # Deposit multiple items into a compost bin in one go farming.compost.all=false +#------- Magic ------- + # Starting value of an item when alchemy starts giving warnings (-1 for never) -magic.alchemy.warningLimit = 25000 +magic.alchemy.warningLimit=25000 + +#------- Slayer ------- + +# Fighting strykewyrms requires a slayer task +slayer.strykewyrmReqTask=true #=================================== # Content & Events diff --git a/game/src/test/kotlin/content/skill/runecrafting/MysteriousRuinsTest.kt b/game/src/test/kotlin/content/skill/runecrafting/MysteriousRuinsTest.kt index e0ca792ceb..504700b07a 100644 --- a/game/src/test/kotlin/content/skill/runecrafting/MysteriousRuinsTest.kt +++ b/game/src/test/kotlin/content/skill/runecrafting/MysteriousRuinsTest.kt @@ -20,7 +20,7 @@ import kotlin.test.assertEquals internal class MysteriousRuinsTest : WorldTest() { @TestFactory - fun `Can enter ruins with talisman`() = RunecraftingTest.altars.map { (type, ruinsTile, altarTile) -> + fun `Can enter ruins with talisman`() = RunecraftingTest.altars.filter { it.ruinsTile != Tile.EMPTY }.map { (type, ruinsTile, altarTile) -> dynamicTest("Enter $type ruins with talisman") { val tile = Areas["${type}_altar_teleport"].random() val player = createPlayer(tile) @@ -39,7 +39,7 @@ internal class MysteriousRuinsTest : WorldTest() { } @TestFactory - fun `Can enter ruins with tiara`() = RunecraftingTest.altars.map { (type, ruinsTile, altarTile) -> + fun `Can enter ruins with tiara`() = RunecraftingTest.altars.filter { it.ruinsTile != Tile.EMPTY }.map { (type, ruinsTile, altarTile) -> dynamicTest("Enter $type ruins with tiara") { val tile = Areas["${type}_altar_teleport"].random() val player = createPlayer(tile) @@ -55,7 +55,7 @@ internal class MysteriousRuinsTest : WorldTest() { } @TestFactory - fun `Can enter ruins with omni tiara`() = RunecraftingTest.altars.map { (type, ruinsTile, altarTile) -> + fun `Can enter ruins with omni tiara`() = RunecraftingTest.altars.filter { it.ruinsTile != Tile.EMPTY }.map { (type, ruinsTile, altarTile) -> dynamicTest("Enter $type ruins with omni tiara") { val tile = Areas["${type}_altar_teleport"].random() val player = createPlayer(tile) @@ -70,7 +70,7 @@ internal class MysteriousRuinsTest : WorldTest() { } @TestFactory - fun `Can enter ruins with omni staff`() = RunecraftingTest.altars.map { (type, ruinsTile, altarTile) -> + fun `Can enter ruins with omni staff`() = RunecraftingTest.altars.filter { it.ruinsTile != Tile.EMPTY }.map { (type, ruinsTile, altarTile) -> dynamicTest("Enter $type ruins with omni tiara") { val tile = Areas["${type}_altar_teleport"].random() val player = createPlayer(tile) @@ -96,7 +96,7 @@ internal class MysteriousRuinsTest : WorldTest() { } @TestFactory - fun `Cannot enter ruins with no items`() = RunecraftingTest.altars.map { (type, ruinsTile, altarTile) -> + fun `Cannot enter ruins with no items`() = RunecraftingTest.altars.filter { it.ruinsTile != Tile.EMPTY }.map { (type, ruinsTile, altarTile) -> dynamicTest("Cannot enter $type ruins") { val tile = Areas["${type}_altar_teleport"].random() val player = createPlayer(tile) diff --git a/game/src/test/kotlin/content/skill/runecrafting/RunecraftingTest.kt b/game/src/test/kotlin/content/skill/runecrafting/RunecraftingTest.kt index 2ee49eed1d..6fef1e7b87 100644 --- a/game/src/test/kotlin/content/skill/runecrafting/RunecraftingTest.kt +++ b/game/src/test/kotlin/content/skill/runecrafting/RunecraftingTest.kt @@ -27,8 +27,7 @@ internal class RunecraftingTest : WorldTest() { @TestFactory fun `Craft runes with rune essence`() = altars.filter { !it.pure }.map { (type, _, altarTile) -> dynamicTest("Craft $type runes with rune essence") { - val tile = teleports.get("${type}_altar_ruins_enter", "Enter").first().to - val player = createPlayer(tile) + val player = createPlayer(altarTile.addY(-1)) player.levels.set(Skill.Runecrafting, 99) player.inventory.add("rune_essence") @@ -46,8 +45,7 @@ internal class RunecraftingTest : WorldTest() { @TestFactory fun `Cant craft high level runes with rune essence`() = altars.filter { it.pure }.map { (type, _, altarTile) -> dynamicTest("Can't craft $type runes with rune essence") { - val tile = teleports.get("${type}_altar_ruins_enter", "Enter").first().to - val player = createPlayer(tile) + val player = createPlayer(altarTile.addY(-1)) player.levels.set(Skill.Runecrafting, 99) player.inventory.add("rune_essence") @@ -65,8 +63,7 @@ internal class RunecraftingTest : WorldTest() { @TestFactory fun `Craft runes with pure essence`() = altars.map { (type, _, altarTile) -> dynamicTest("Craft $type runes with pure essence") { - val tile = teleports.get("${type}_altar_ruins_enter", "Enter").first().to - val player = createPlayer(tile) + val player = createPlayer(altarTile.addY(-1)) player.levels.set(Skill.Runecrafting, 99) player.inventory.add("pure_essence") @@ -82,7 +79,7 @@ internal class RunecraftingTest : WorldTest() { } @TestFactory - fun `Can craft multiple runes with one essence`() = altars.filter { it.type != "law" && it.type != "death" && it.type != "blood" }.map { (type, _, altarTile) -> + fun `Can craft multiple runes with one essence`() = altars.filter { it.type != "law" && it.type != "death" && it.type != "blood" && it.type != "astral" }.map { (type, _, altarTile) -> dynamicTest("Craft multiple $type runes with pure essence") { val tile = teleports.get("${type}_altar_ruins_enter", "Enter").first().to val player = createPlayer(tile) @@ -103,8 +100,7 @@ internal class RunecraftingTest : WorldTest() { @TestFactory fun `Cant craft runes without required level`() = altars.map { (type, _, altarTile) -> dynamicTest("Can't craft $type runes") { - val tile = teleports.get("${type}_altar_ruins_enter", "Enter").first().to - val player = createPlayer(tile) + val player = createPlayer(altarTile.addY(-1)) player.levels.set(Skill.Runecrafting, 0) player.inventory.add("pure_essence") @@ -135,6 +131,7 @@ internal class RunecraftingTest : WorldTest() { Altar("chaos", Tile(3059, 3590), Tile(2270, 4841), pure = true), Altar("death", Tile(1860, 4638), Tile(2204, 4835), pure = true), Altar("blood", Tile(3560, 9780), Tile(2461, 4894, 1), pure = true), + Altar("astral", Tile.EMPTY, Tile(2157, 3863), pure = true), ) } }