diff --git a/cache/src/main/kotlin/world/gregs/voidps/cache/definition/decoder/ClientScriptDecoder.kt b/cache/src/main/kotlin/world/gregs/voidps/cache/definition/decoder/ClientScriptDecoder.kt index d5d135938d..01054eb149 100644 --- a/cache/src/main/kotlin/world/gregs/voidps/cache/definition/decoder/ClientScriptDecoder.kt +++ b/cache/src/main/kotlin/world/gregs/voidps/cache/definition/decoder/ClientScriptDecoder.kt @@ -78,10 +78,10 @@ class ClientScriptDecoder(private val revision667: Boolean = false) : Definition if (intOperands == null) { intOperands = IntArray(instructionCount) } - if (clientOpcode < 150 && clientOpcode != 21 && clientOpcode != 38 && clientOpcode != 39) { - intOperands!![index] = buffer.readInt() - } else { + if (clientOpcode >= (if (revision667) 150 else 100) || clientOpcode == 21 || clientOpcode == 38 || clientOpcode == 39) { intOperands!![index] = buffer.readUnsignedByte() + } else { + intOperands!![index] = buffer.readInt() } } instructions[index++] = clientOpcode diff --git a/data/area/kharidian_desert/al_kharid/shantay_pass/shantay_pass.anims.toml b/data/area/kharidian_desert/al_kharid/shantay_pass/shantay_pass.anims.toml index 158135eee3..af2e805e19 100644 --- a/data/area/kharidian_desert/al_kharid/shantay_pass/shantay_pass.anims.toml +++ b/data/area/kharidian_desert/al_kharid/shantay_pass/shantay_pass.anims.toml @@ -1,8 +1,8 @@ [ugthanki_attack] -id = 49 +id = 9666 [ugthanki_defend] -id = 50 +id = 9667 [ugthanki_death] -id = 52 +id = 9674 diff --git a/data/area/kharidian_desert/kalphite_hive/kalphite.anims.toml b/data/area/kharidian_desert/kalphite_hive/kalphite.anims.toml new file mode 100644 index 0000000000..8e4ee10791 --- /dev/null +++ b/data/area/kharidian_desert/kalphite_hive/kalphite.anims.toml @@ -0,0 +1,59 @@ +[kalphite_attack] +id = 6223 + +[kalphite_guardian_attack] +id = 6226 + +[kalphite_defend] +id = 6227 + +[kalphite_death] +id = 6228 + +[kalphite_guardian_death] +id = 6230 + +[kalphite_queen_defend] +id = 6232 + +[kalphite_queen_attack_ranged] +id = 6240 + +[kalphite_queen_lightning] +id = 1172 + +[kalphite_queen_attack_mandibles] +id = 6241 + +[kalphite_queen_attack_claws] +id = 6476 + +[kalphite_queen_death] +id = 6242 + +[kalphite_queen_airborne_ranged] +id = 6234 + +[kalphite_queen_airborne_melee] +id = 1170 + +[kalphite_queen_airborne_claws] +id = 1178 + +[kalphite_queen_airborne_defend] +id = 6237 + +[kalphite_queen_airborne_death] +id = 6233 + +[kalphite_queen_emerging] +id = 6270 + +[kalphite_cocoon_break] +id = 6272 + +[kalphite_cocoon_return] +id = 6273 + +[kalphite_cocoon_idle] +id = 6274 \ No newline at end of file diff --git a/data/area/kharidian_desert/kalphite_hive/kalphite.combat.toml b/data/area/kharidian_desert/kalphite_hive/kalphite.combat.toml new file mode 100644 index 0000000000..f21123209f --- /dev/null +++ b/data/area/kharidian_desert/kalphite_hive/kalphite.combat.toml @@ -0,0 +1,109 @@ +[kalphite] +attack_speed = 4 +retreat_range = 15 +defend_anim = "human_defend" +defend_sound = "kalphite_defend" +death_anim = "human_death" +death_sound = "kalphite_death" + +[kalphite.melee] +range = 1 +anim = "human_attack" +target_sound = "kalphite_attack" +target_hit = { offense = "crush", max = 80 } + +[kalphite_worker] +attack_speed = 4 +retreat_range = 8 +defend_anim = "kalphite_defend" +defend_sound = "kalphite_defend" +death_anim = "kalphite_death" +death_sound = "kalphite_death" + +[kalphite_worker.melee] +range = 1 +anim = "kalphite_attack" +target_sound = "kalphite_attack" +target_hit = { offense = "crush", max = 30 } + +[kalphite_guardian] +clone = "kalphite_worker" +death_anim = "kalphite_guardian_death" + +[kalphite_guardian.melee] +clone = "kalphite_worker.melee" +anim = "kalphite_guardian_attack" +target_hit = { offense = "crush", max = 120 } + +[kalphite_guardian.melee_poison] # Unknown chance +clone = "kalphite_guardian.melee" +impact_poison = 60 + +[kalphite_queen] +attack_speed = 4 +retreat_range = 12 +defend_anim = "kalphite_queen_defend" +defend_sound = "kalphite_queen_defend" +death_anim = "kalphite_death" +death_sound = "kalphite_queen_death" + +[kalphite_queen.melee] +range = 1 +anim = "kalphite_queen_attack_mandibles" +target_sound = "kalphite_mandibles" +target_hit = { offense = "stab", max = 310 } + +[kalphite_queen.claws] +range = 1 +anim = "kalphite_queen_attack_claws" +target_sound = "kalphite_queen_attack" +target_hit = { offense = "stab", max = 310 } + +[kalphite_queen.range] +range = 10 +anim = "kalphite_queen_attack_ranged" +target_sound = "kalphite_queen_spines" +projectile = "kaplhite_queen_spines" +projectile_origin_x = 2 +projectile_origin_y = 2 +multi_target_area = "kalphite_queen_lair" +target_hit = { offense = "range", max = 310 } + +[kalphite_queen.magic] +range = 10 +anim = "kalphite_queen_lightning" +gfx = "kalphite_queen_lightning_cast" +sound = { id = "kalphite_lighting", radius = 16 } +projectile = "kalphite_queen_lightning_travel" +projectile_origin_x = 2 +projectile_origin_y = 2 +impact_sound = { id = "kalphite_lighting_impact", radius = 10 } +impact_gfx = "kalphite_queen_lightning_impact" +target_hit = { offense = "magic", max = 310 } + +[kalphite_queen_airborne] +attack_speed = 4 +retreat_range = 12 +defend_anim = "kalphite_queen_airborne_defend" +defend_sound = "kalphite_queen_airborne_defend" +death_anim = "kalphite_queen_airborne_death" +death_sound = "kalphite_queen_airborne_death" + +[kalphite_queen_airborne.melee] +clone = "kalphite_queen.melee" +anim = "kalphite_queen_airborne_melee" +target_sound = "kalphite_queen_airborne_melee" + +[kalphite_queen_airborne.claws] +clone = "kalphite_queen.claws" +anim = "kalphite_queen_airborne_claws" + +[kalphite_queen_airborne.range] +clone = "kalphite_queen.range" +anim = "kalphite_queen_airborne_ranged" + +[kalphite_queen_airborne.magic] +clone = "kalphite_queen.magic" +anim = "kalphite_queen_airborne_ranged" +gfx = "kalphite_queen_airborne_lightning" +target_sound = "kalphite_queen_lighting_glow" diff --git a/data/entity/npc/monster/kalphite/kalphite.drops.toml b/data/area/kharidian_desert/kalphite_hive/kalphite.drops.toml similarity index 100% rename from data/entity/npc/monster/kalphite/kalphite.drops.toml rename to data/area/kharidian_desert/kalphite_hive/kalphite.drops.toml diff --git a/data/area/kharidian_desert/kalphite_hive/kalphite.gfx.toml b/data/area/kharidian_desert/kalphite_hive/kalphite.gfx.toml new file mode 100644 index 0000000000..f8f5c50fcd --- /dev/null +++ b/data/area/kharidian_desert/kalphite_hive/kalphite.gfx.toml @@ -0,0 +1,27 @@ +[kalphite_queen_lightning_cast] +id = 278 + +[kalphite_queen_airborne_lightning] +id = 279 + +[kalphite_queen_lightning_travel] +id = 280 +curve = 10 +delay = 45 +# Approx +time_offset = 10 +multiplier = 8 + +[kalphite_queen_emerging] +id = 1055 + +[kalphite_queen_lightning_impact] +id = 281 + +[kaplhite_queen_spines] +id = 288 +curve = 20 +delay = 30 + +[kaplhite_queen_spines_red] +id = 289 diff --git a/data/area/kharidian_desert/kalphite_hive/kalphite.sounds.toml b/data/area/kharidian_desert/kalphite_hive/kalphite.sounds.toml new file mode 100644 index 0000000000..fc8c63422c --- /dev/null +++ b/data/area/kharidian_desert/kalphite_hive/kalphite.sounds.toml @@ -0,0 +1,47 @@ +[kalphite_attack] +id = 537 + +[kalphite_death] +id = 538 + +[kalphite_defend] +id = 539 + +[kalphite_queen_attack] +id = 563 + +[kalphite_lighting] +id = 557 + +[kalphite_lighting_impact] +id = 559 + +[kalphite_queen_defend] +id = 565 + +[kalphite_mandibles] +id = 574 + +[kalphite_queen_spines] +id = 555 + +[kalphite_crack_open] +id = 552 + +[kalphite_queen_death] +id = 564 + +[kalphite_cocoon_break] +id = 556 + +[kalphite_queen_airborne_death] +id = 553 + +[kalphite_queen_airborne_defend] +id = 554 + +[kalphite_queen_airborne_melee] +id = 551 + +[kalphite_queen_lighting_glow] +id = 558 diff --git a/data/entity/npc/boss/kalphite_queen/kalphite_queen.areas.toml b/data/area/kharidian_desert/kalphite_hive/kalphite_hive.areas.toml similarity index 67% rename from data/entity/npc/boss/kalphite_queen/kalphite_queen.areas.toml rename to data/area/kharidian_desert/kalphite_hive/kalphite_hive.areas.toml index 3fb2602f68..e55512c337 100644 --- a/data/entity/npc/boss/kalphite_queen/kalphite_queen.areas.toml +++ b/data/area/kharidian_desert/kalphite_hive/kalphite_hive.areas.toml @@ -1,4 +1,4 @@ -[kalphite_queen_multi_area] +[kalphite_queen_lair] x = [3456, 3519] y = [9472, 9535] tags = ["multi_combat"] diff --git a/data/area/kharidian_desert/kalphite_hive/kalphite_hive.item-spawns.toml b/data/area/kharidian_desert/kalphite_hive/kalphite_hive.item-spawns.toml new file mode 100644 index 0000000000..fadf5854bb --- /dev/null +++ b/data/area/kharidian_desert/kalphite_hive/kalphite_hive.item-spawns.toml @@ -0,0 +1,12 @@ +spawns = [ + # Hive + { id = "potato_cactus", x = 3460, y = 9484, level = 2, delay = 65, members = true }, + { id = "potato_cactus", x = 3461, y = 9480, level = 2, delay = 65, members = true }, + { id = "potato_cactus", x = 3465, y = 9477, level = 2, delay = 65, members = true }, + ## Lair + { id = "potato_cactus", x = 3480, y = 9483, delay = 65, members = true }, + { id = "potato_cactus", x = 3469, y = 9492, delay = 65, members = true }, + { id = "potato_cactus", x = 3469, y = 9498, delay = 65, members = true }, + { id = "potato_cactus", x = 3474, y = 9509, delay = 65, members = true }, + { id = "potato_cactus", x = 3487, y = 9517, delay = 65, members = true }, +] \ No newline at end of file diff --git a/data/area/kharidian_desert/kalphite_hive/kalphite_hive.npc-spawns.toml b/data/area/kharidian_desert/kalphite_hive/kalphite_hive.npc-spawns.toml index fe9fb7f2c4..911dc5eeae 100644 --- a/data/area/kharidian_desert/kalphite_hive/kalphite_hive.npc-spawns.toml +++ b/data/area/kharidian_desert/kalphite_hive/kalphite_hive.npc-spawns.toml @@ -1,5 +1,32 @@ spawns = [ - { id = "weird_old_man", x = 3232, y = 3108 }, + # Kalphite Lair + { id = "kalphite_worker", x = 3508, y = 9525, level = 2, members = true }, + { id = "kalphite_worker", x = 3505, y = 9520, level = 2, members = true }, + { id = "kalphite_worker", x = 3503, y = 9527, level = 2, members = true }, + { id = "kalphite_worker", x = 3500, y = 9520, level = 2, members = true }, + { id = "kalphite_worker", x = 3499, y = 9511, level = 2, members = true }, + { id = "kalphite_worker", x = 3497, y = 9476, level = 2, members = true }, + { id = "kalphite_worker", x = 3495, y = 9501, level = 2, members = true }, + { id = "kalphite_worker", x = 3493, y = 9510, level = 2, members = true }, + { id = "kalphite_worker", x = 3488, y = 9490, level = 2, members = true }, + { id = "kalphite_worker", x = 3482, y = 9526, level = 2, members = true }, + { id = "kalphite_worker", x = 3479, y = 9478, level = 2, members = true }, + { id = "kalphite_worker", x = 3472, y = 9516, level = 2, members = true }, + { id = "kalphite_worker", x = 3465, y = 9502, level = 2, members = true }, + { id = "kalphite_soldier", x = 3494, y = 9491, level = 2, members = true }, + { id = "kalphite_soldier", x = 3477, y = 9501, level = 2, members = true }, + { id = "kalphite_soldier", x = 3469, y = 9481, level = 2, members = true }, + { id = "kalphite_soldier", x = 3467, y = 9489, level = 2, members = true }, + { id = "kalphite_soldier", x = 3466, y = 9476, level = 2, members = true }, + { id = "kalphite_soldier", x = 3465, y = 9486, level = 2, members = true }, + { id = "kalphite_soldier", x = 3463, y = 9481, level = 2, members = true }, + { id = "kalphite_guardian", x = 3511, y = 9499, level = 2, members = true }, + { id = "kalphite_guardian", x = 3505, y = 9493, level = 2, members = true }, + { id = "kalphite_guardian_2", x = 3496, y = 9502, members = true }, + { id = "kalphite_guardian_2", x = 3495, y = 9489, members = true }, + # Kalphite Hive + { id = "kalphite_guardian", x = 3545, y = 9507, members = true }, + { id = "kalphite_guardian", x = 3556, y = 9503, members = true }, { id = "kalphite_soldier", x = 3545, y = 9495 }, { id = "kalphite_soldier", x = 3546, y = 9503 }, { id = "kalphite_soldier", x = 3551, y = 9497 }, @@ -13,6 +40,8 @@ spawns = [ { id = "kalphite_larva", x = 3491, y = 9498 }, { id = "kalphite_larva", x = 3493, y = 9492 }, { id = "kalphite_larva", x = 3495, y = 9508 }, + # Entrance + { id = "weird_old_man", x = 3232, y = 3108 }, { id = "goat", x = 3205, y = 3109, members = true }, { id = "goat", x = 3206, y = 3108, members = true }, { id = "goat", x = 3207, y = 3107, members = true }, diff --git a/data/area/kharidian_desert/kalphite_hive/kalphite_hive.npcs.toml b/data/area/kharidian_desert/kalphite_hive/kalphite_hive.npcs.toml index 1a3102b529..ef99afb4da 100644 --- a/data/area/kharidian_desert/kalphite_hive/kalphite_hive.npcs.toml +++ b/data/area/kharidian_desert/kalphite_hive/kalphite_hive.npcs.toml @@ -5,10 +5,10 @@ att = 300 str = 300 def = 300 mage = 150 -style = "stab" -max_hit_melee = 310 +height = 60 +combat_def = "kalphite_queen" xp_bonus = 0.5 -hunt_mode = "cowardly" +hunt_mode = "aggressive" slayer_xp = 535.5 categories = ["kalphite", "bosses"] aka = ["kq"] @@ -18,21 +18,60 @@ examine = "I don't think insect repellent will work..." [kalphite_queen_airborne] id = 1160 -hitpoints = 2550 -att = 300 -str = 300 -def = 300 -mage = 150 -style = "stab" -max_hit_melee = 310 +clone = "kalphite_queen" +combat_def = "kalphite_queen_airborne" xp_bonus = 12.5 + +[kalphite_worker] +id = 1153 +hitpoints = 400 +att = 20 +str = 20 +def = 20 +combat_def = "kalphite_worker" +slayer_xp = 40.0 +respawn_delay = 25 +wander_range = 6 hunt_mode = "cowardly" -slayer_xp = 535.5 -categories = ["kalphite", "bosses"] -aka = ["kq"] -drop_table = "kalphite_queen" +drop_table = "kalphite_worker" +categories = ["kalphites"] +examine = "I don't think insect repellent will work..." + +[kalphite_soldier] +id = 1154 +hitpoints = 900 +att = 70 +str = 70 +def = 70 +combat_def = "kalphite_worker" +max_hit_crush = 80 +slayer_xp = 90.0 +respawn_delay = 25 +wander_range = 6 +hunt_mode = "cowardly" +drop_table = "kalphite_soldier" +categories = ["kalphites"] examine = "I don't think insect repellent will work..." +[kalphite_guardian] +id = 1155 +hitpoints = 1700 +att = 110 +str = 110 +def = 110 +combat_def = "kalphite_guardian" +slayer_xp = 170.0 +respawn_delay = 40 +wander_range = 6 +hunt_mode = "cowardly" +drop_table = "kalphite_guardian" +categories = ["kalphites"] +examine = "I don't think insect repellent will work..." + +[kalphite_guardian_2] +id = 1157 +clone = "kalphite_guardian" + [weird_old_man] id = 1152 examine = "What's he mumbling about?" diff --git a/data/area/kharidian_desert/kalphite_hive/kalphite_hive.objs.toml b/data/area/kharidian_desert/kalphite_hive/kalphite_hive.objs.toml new file mode 100644 index 0000000000..ecfaf50505 --- /dev/null +++ b/data/area/kharidian_desert/kalphite_hive/kalphite_hive.objs.toml @@ -0,0 +1,27 @@ +[kalphite_hive_tunnel] +id = 3827 +examine = "How am I going to get down there?" + +[kalphite_hive_tunnel_rope] +id = 3828 + +[kalphite_hive_exit_rope] +id = 3829 + +[kalphite_hive_wall_tunnel] +id = 23596 + +[kalphite_lair_entrance] +id = 23609 + +[kalphite_lair_entrance_rope] +id = 23610 + +[kalphite_lair_exit_rope] +id = 3832 + +[kalphite_queen_emerging_legs] +id = 23591 + +[kalphite_cocoon] +id = 23611 diff --git a/data/area/kharidian_desert/kalphite_hive/kalphite_hive.teles.toml b/data/area/kharidian_desert/kalphite_hive/kalphite_hive.teles.toml new file mode 100644 index 0000000000..04f4287b5a --- /dev/null +++ b/data/area/kharidian_desert/kalphite_hive/kalphite_hive.teles.toml @@ -0,0 +1,19 @@ +[kalphite_hive_tunnel_rope] +option = "Climb-down" +tile = { x = 3227, y = 3108 } +to = { x = 3484, y = 9510, level = 2 } + +[kalphite_hive_exit_rope] +option = "Climb-up" +tile = { x = 3483, y = 9510, level = 2 } +to = { x = 3226, y = 3108 } + +[kalphite_lair_entrance_rope] +option = "Climb-down" +tile = { x = 3509, y = 9497, level = 2 } +to = { x = 3507, y = 9494 } + +[kalphite_lair_exit_rope] +option = "Climb-up" +tile = { x = 3508, y = 9494 } +to = { x = 3509, y = 9496, level = 2 } diff --git a/data/area/kharidian_desert/kalphite_hive/kalphite_hive.varbits.toml b/data/area/kharidian_desert/kalphite_hive/kalphite_hive.varbits.toml new file mode 100644 index 0000000000..fb51f06344 --- /dev/null +++ b/data/area/kharidian_desert/kalphite_hive/kalphite_hive.varbits.toml @@ -0,0 +1,9 @@ +[kalphite_tunnel_rope] +id = 7262 +format = "boolean" +persist = true + +[kalphite_lair_rope] +id = 7263 +format = "boolean" +persist = true \ No newline at end of file diff --git a/data/client/client.scripts.toml b/data/client/client.scripts.toml index 92d145d64b..a65b142d6c 100644 --- a/data/client/client.scripts.toml +++ b/data/client/client.scripts.toml @@ -288,4 +288,20 @@ params = [ id = 917 [reset_summoning_orb] -id = 2471 \ No newline at end of file +id = 2471 + +[camera_zoom_reset_black_bars] +id = 1097 + +[camera_zoom_out_fov] +id = 1098 + +[camera_unlock] +id = 2611 +params = [ + "zoom", + "unknown" +] + +[camera_zoom_out] +id = 2619 \ No newline at end of file diff --git a/data/entity/npc/monster/kalphite/kalphite.anims.toml b/data/entity/npc/monster/kalphite/kalphite.anims.toml deleted file mode 100644 index 876096edcf..0000000000 --- a/data/entity/npc/monster/kalphite/kalphite.anims.toml +++ /dev/null @@ -1,14 +0,0 @@ -[kalphite_attack] -id = 6223 - -[kalphite_guardian_attack] -id = 6226 - -[kalphite_defend] -id = 6227 - -[kalphite_death] -id = 6228 - -[kalphite_guardian_death] -id = 6230 diff --git a/data/entity/npc/monster/kalphite/kalphite.combat.toml b/data/entity/npc/monster/kalphite/kalphite.combat.toml deleted file mode 100644 index 376fb3a261..0000000000 --- a/data/entity/npc/monster/kalphite/kalphite.combat.toml +++ /dev/null @@ -1,26 +0,0 @@ -[kalphite_worker] -attack_speed = 4 -retreat_range = 8 -defend_anim = "kalphite_defend" -defend_sound = "kalphite_defend" -death_anim = "kalphite_death" -death_sound = "kalphite_death" - -[kalphite_worker.melee] -range = 1 -anim = "kalphite_attack" -target_sound = "kalphite_attack" -target_hit = { offense = "crush", max = 30 } - -[kalphite_guardian] -clone = "kalphite_worker" -death_anim = "kalphite_guardian_death" - -[kalphite_guardian.melee] -clone = "kalphite_worker.melee" -anim = "kalphite_guardian_attack" -target_hit = { offense = "crush", max = 120 } - -[kalphite_guardian.melee_poison] # Unknown chance -clone = "kalphite_guardian.melee" -impact_poison = 60 diff --git a/data/entity/npc/monster/kalphite/kalphite.npc-spawns.toml b/data/entity/npc/monster/kalphite/kalphite.npc-spawns.toml deleted file mode 100644 index 3745078897..0000000000 --- a/data/entity/npc/monster/kalphite/kalphite.npc-spawns.toml +++ /dev/null @@ -1,30 +0,0 @@ -spawns = [ - # Kalphite Lair - { id = "kalphite_worker", x = 3508, y = 9525, level = 2, members = true }, - { id = "kalphite_worker", x = 3505, y = 9520, level = 2, members = true }, - { id = "kalphite_worker", x = 3503, y = 9527, level = 2, members = true }, - { id = "kalphite_worker", x = 3500, y = 9520, level = 2, members = true }, - { id = "kalphite_worker", x = 3499, y = 9511, level = 2, members = true }, - { id = "kalphite_worker", x = 3497, y = 9476, level = 2, members = true }, - { id = "kalphite_worker", x = 3495, y = 9501, level = 2, members = true }, - { id = "kalphite_worker", x = 3493, y = 9510, level = 2, members = true }, - { id = "kalphite_worker", x = 3488, y = 9490, level = 2, members = true }, - { id = "kalphite_worker", x = 3482, y = 9526, level = 2, members = true }, - { id = "kalphite_worker", x = 3479, y = 9478, level = 2, members = true }, - { id = "kalphite_worker", x = 3472, y = 9516, level = 2, members = true }, - { id = "kalphite_worker", x = 3465, y = 9502, level = 2, members = true }, - { id = "kalphite_soldier", x = 3494, y = 9491, level = 2, members = true }, - { id = "kalphite_soldier", x = 3477, y = 9501, level = 2, members = true }, - { id = "kalphite_soldier", x = 3469, y = 9481, level = 2, members = true }, - { id = "kalphite_soldier", x = 3467, y = 9489, level = 2, members = true }, - { id = "kalphite_soldier", x = 3466, y = 9476, level = 2, members = true }, - { id = "kalphite_soldier", x = 3465, y = 9486, level = 2, members = true }, - { id = "kalphite_soldier", x = 3463, y = 9481, level = 2, members = true }, - { id = "kalphite_guardian", x = 3511, y = 9499, level = 2, members = true }, - { id = "kalphite_guardian", x = 3505, y = 9493, level = 2, members = true }, - { id = "kalphite_guardian_2", x = 3496, y = 9502, members = true }, - { id = "kalphite_guardian_2", x = 3495, y = 9489, members = true }, - # Kalphite Hive - { id = "kalphite_guardian", x = 3545, y = 9507, members = true }, - { id = "kalphite_guardian", x = 3556, y = 9503, members = true }, -] \ No newline at end of file diff --git a/data/entity/npc/monster/kalphite/kalphite.npcs.toml b/data/entity/npc/monster/kalphite/kalphite.npcs.toml deleted file mode 100644 index 01071836c8..0000000000 --- a/data/entity/npc/monster/kalphite/kalphite.npcs.toml +++ /dev/null @@ -1,49 +0,0 @@ -[kalphite_worker] -id = 1153 -hitpoints = 400 -att = 20 -str = 20 -def = 20 -combat_def = "kalphite_worker" -slayer_xp = 40.0 -respawn_delay = 25 -wander_range = 6 -hunt_mode = "cowardly" -drop_table = "kalphite_worker" -categories = ["kalphites"] -examine = "I don't think insect repellent will work..." - -[kalphite_soldier] -id = 1154 -hitpoints = 900 -att = 70 -str = 70 -def = 70 -combat_def = "kalphite_worker" -max_hit_crush = 80 -slayer_xp = 90.0 -respawn_delay = 25 -wander_range = 6 -hunt_mode = "cowardly" -drop_table = "kalphite_soldier" -categories = ["kalphites"] -examine = "I don't think insect repellent will work..." - -[kalphite_guardian] -id = 1155 -hitpoints = 1700 -att = 110 -str = 110 -def = 110 -combat_def = "kalphite_guardian" -slayer_xp = 170.0 -respawn_delay = 40 -wander_range = 6 -hunt_mode = "cowardly" -drop_table = "kalphite_guardian" -categories = ["kalphites"] -examine = "I don't think insect repellent will work..." - -[kalphite_guardian_2] -id = 1157 -clone = "kalphite_guardian" \ No newline at end of file diff --git a/data/entity/npc/monster/kalphite/kalphite.sounds.toml b/data/entity/npc/monster/kalphite/kalphite.sounds.toml deleted file mode 100644 index 85a0da3ec8..0000000000 --- a/data/entity/npc/monster/kalphite/kalphite.sounds.toml +++ /dev/null @@ -1,8 +0,0 @@ -[kalphite_attack] -id = 537 - -[kalphite_death] -id = 538 - -[kalphite_defend] -id = 539 diff --git a/data/entity/player/modal/toplevel/gameframe.ifaces.toml b/data/entity/player/modal/toplevel/gameframe.ifaces.toml index 01ea71e83c..79447a3bf1 100644 --- a/data/entity/player/modal/toplevel/gameframe.ifaces.toml +++ b/data/entity/player/modal/toplevel/gameframe.ifaces.toml @@ -482,3 +482,6 @@ id = 42 id = 49 options = { Select = 0 } +[orb_of_oculus] +id = 475 +type = "full_screen" \ No newline at end of file diff --git a/engine/src/main/kotlin/world/gregs/voidps/engine/data/ConfigFiles.kt b/engine/src/main/kotlin/world/gregs/voidps/engine/data/ConfigFiles.kt index ccd764fa77..06bdc50c10 100644 --- a/engine/src/main/kotlin/world/gregs/voidps/engine/data/ConfigFiles.kt +++ b/engine/src/main/kotlin/world/gregs/voidps/engine/data/ConfigFiles.kt @@ -33,10 +33,7 @@ fun configFiles(): ConfigFiles { val map = Object2ObjectOpenHashMap>() val data = Path.of(Settings["storage.data"]) val modified = Path.of(Settings["storage.data.modified"]) - val parent = modified.parent - if (parent.notExists()) { - parent.createDirectories() - } + modified.createParentDirectories() val lastUpdated = loadLastUpdate(modified) val extensions = mutableSetOf() timedLoad("config file path") { diff --git a/engine/src/main/kotlin/world/gregs/voidps/engine/entity/character/Death.kt b/engine/src/main/kotlin/world/gregs/voidps/engine/entity/character/Death.kt index 815e6e4f2a..156f32f5b8 100644 --- a/engine/src/main/kotlin/world/gregs/voidps/engine/entity/character/Death.kt +++ b/engine/src/main/kotlin/world/gregs/voidps/engine/entity/character/Death.kt @@ -27,9 +27,17 @@ interface Death { } } + fun npcCanDie(npc: String = "*", handler: NPC.() -> Boolean) { + Script.checkLoading() + Wildcards.find(npc, Wildcard.Npc) { id -> + npcDeathHandlers.getOrPut(id) { mutableListOf() }.add(handler) + } + } + companion object : AutoCloseable { private val playerHandlers = ObjectArrayList Unit>(20) private val npcHandlers = Object2ObjectOpenHashMap Unit>>(20) + private val npcDeathHandlers = Object2ObjectOpenHashMap Boolean>>(20) fun killed(player: Player): OnDeath { val onDeath = OnDeath() @@ -48,6 +56,20 @@ interface Death { } } + fun canDie(npc: NPC): Boolean { + for (handler in npcDeathHandlers[npc.id] ?: emptyList()) { + if (!handler.invoke(npc)) { + return false + } + } + for (handler in npcDeathHandlers["*"] ?: emptyList()) { + if (!handler.invoke(npc)) { + return false + } + } + return true + } + override fun close() { playerHandlers.clear() npcHandlers.clear() diff --git a/game/src/main/kotlin/content/area/fremennik_province/rellekka/Rockslug.kt b/game/src/main/kotlin/content/area/fremennik_province/rellekka/Rockslug.kt index cae9c1c4a9..570d66146e 100644 --- a/game/src/main/kotlin/content/area/fremennik_province/rellekka/Rockslug.kt +++ b/game/src/main/kotlin/content/area/fremennik_province/rellekka/Rockslug.kt @@ -24,6 +24,7 @@ class Rockslug : Script { } salt(this, target) } + npcLevelChanged(Skill.Constitution, "rockslug*", ::killingBlow) } diff --git a/game/src/main/kotlin/content/area/kharidian_desert/kalphite_lair/KalphiteHive.kt b/game/src/main/kotlin/content/area/kharidian_desert/kalphite_lair/KalphiteHive.kt new file mode 100644 index 0000000000..2983d12947 --- /dev/null +++ b/game/src/main/kotlin/content/area/kharidian_desert/kalphite_lair/KalphiteHive.kt @@ -0,0 +1,31 @@ +package content.area.kharidian_desert.kalphite_lair + +import world.gregs.voidps.engine.Script +import world.gregs.voidps.engine.client.message +import world.gregs.voidps.engine.inv.inventory +import world.gregs.voidps.engine.inv.remove + +class KalphiteHive : Script { + init { + playerSpawn { + sendVariable("kalphite_tunnel_rope") + sendVariable("kalphite_lair_rope") + } + + itemOnObjectOperate("rope", "kalphite_hive_tunnel") { + if (!get("kalphite_tunnel_rope", false) && inventory.remove("rope")) { + set("kalphite_tunnel_rope", true) + } + } + + itemOnObjectOperate("rope", "kalphite_lair_entrance") { + if (!get("kalphite_lair_rope", false) && inventory.remove("rope")) { + set("kalphite_lair_rope", true) + } + } + + objectOperate("Enter", "kalphite_hive_wall_tunnel") { + message("It looks like the tunnel is blocked at the other end.") + } + } +} diff --git a/game/src/main/kotlin/content/area/kharidian_desert/kalphite_lair/KalphiteQueen.kt b/game/src/main/kotlin/content/area/kharidian_desert/kalphite_lair/KalphiteQueen.kt new file mode 100644 index 0000000000..4df60b8a46 --- /dev/null +++ b/game/src/main/kotlin/content/area/kharidian_desert/kalphite_lair/KalphiteQueen.kt @@ -0,0 +1,179 @@ +package content.area.kharidian_desert.kalphite_lair + +import content.area.wilderness.inMultiCombat +import content.entity.combat.Target +import content.entity.combat.attackers +import content.entity.combat.hit.hit +import content.entity.combat.target +import content.entity.effect.clearTransform +import content.entity.effect.transform +import content.entity.proj.shoot +import org.rsmod.game.pathfinder.LineValidator +import world.gregs.voidps.engine.Script +import world.gregs.voidps.engine.client.instruction.handle.interactPlayer +import world.gregs.voidps.engine.client.variable.start +import world.gregs.voidps.engine.entity.character.Character +import world.gregs.voidps.engine.entity.character.areaSound +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.mode.move.hasLineOfSight +import world.gregs.voidps.engine.entity.character.npc.NPC +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.Players +import world.gregs.voidps.engine.entity.character.player.skill.Skill +import world.gregs.voidps.engine.entity.item.Item +import world.gregs.voidps.engine.entity.obj.GameObjects +import world.gregs.voidps.engine.map.spiral +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.Direction +import world.gregs.voidps.type.Distance +import world.gregs.voidps.type.Tile +import world.gregs.voidps.type.random +import java.util.concurrent.TimeUnit + +class KalphiteQueen(val lineOfSight: LineValidator) : Script { + init { + npcCombatDamage("kalphite_queen") { + if (random.nextInt(20) != 0) { + return@npcCombatDamage + } + spawnWorker(it.source) + } + + npcCombatPrepare("kalphite_queen*") { + clear("chain_hits") + true + } + + npcCombatAttack("kalphite_queen*") { + if (it.type == "range" && it.damage > 0) { + it.target.levels.drain(Skill.Prayer, 1) + } else if (it.type == "magic") { + set("chain_hits", mutableSetOf(it.target.index)) + chainGlow(this, it.target) + } + } + + npcCanDie("kalphite_queen") { + transform == "kalphite_queen_airborne" + } + + npcLevelChanged(Skill.Constitution, "kalphite_queen") { _, _, to -> + if (to > 10) { + return@npcLevelChanged + } + if (transform == "kalphite_queen_airborne") { + return@npcLevelChanged + } + val target = target + levels.restore(Skill.Constitution, 2550) + for (attacker in attackers) { + attacker.mode = EmptyMode + } + mode = PauseMode + steps.clear() + clearFace() + clearWatch() + start("movement_delay", 10) + clearAnim() + anim("kalphite_queen_death") + areaSound("kalphite_queen_death", tile, radius = 20) + softQueue("emerging", 14) { + if (target is Player) { + interactPlayer(target, "Attack") + } else { + mode = EmptyMode + } + } + softQueue("emerge", 2) { + anim("kalphite_queen_emerging") + gfx("kalphite_queen_emerging") + GameObjects.add("kalphite_queen_emerging_legs", tile, ticks = 8) + transform("kalphite_queen_airborne") + } + softTimers.start("kalphite_queen_revert") + } + + npcTimerStart("kalphite_queen_revert") { + TimeUnit.MINUTES.toTicks(20) + } + + npcTimerTick("kalphite_queen_revert") { + // TODO what if in combat? + clearTransform() + Timer.CANCEL + } + } + + fun chainGlow(source: NPC, target: Character) { + if (target !is Player || !target.inMultiCombat) { + return + } + val chain: MutableSet = source.getOrPut("chain_hits") { mutableSetOf() } + for (tile in target.tile.spiral(4)) { + for (player in Players.at(tile)) { + if (chain.contains(player.index) || !Target.attackable(source, player)) { + continue + } + + if (!lineOfSight.hasLineOfSight(target, player)) { + continue + } + chain.add(player.index) + val time = target.shoot(id = "kalphite_queen_lightning_travel", target = player) + source.hit(player, Item.EMPTY, "magic", special = true, delay = time) + return + } + } + } + + private fun NPC.spawnWorker(source: Character?) { + if (queue.contains("cocoon_idle")) { + return + } + for (objTile in listOf( + Tile(3482, 9502), + Tile(3486, 9498), + Tile(3490, 9502), + Tile(3486, 9506), + Tile(3493, 9483), + Tile(3480, 9481), + Tile(3477, 9481), + Tile(3464, 9495), + Tile(3472, 9508), + Tile(3486, 9518), + Tile(3488, 9518), + Tile(3502, 9504), + Tile(3502, 9501), + )) { + val nearest = Distance.nearest(tile, size, size, objTile) + val distance = nearest.distanceTo(objTile) + if (distance > 4) { // TODO actual distance + continue + } + val cocoon = GameObjects.findOrNull(objTile, "kalphite_cocoon") ?: continue + areaSound("kalphite_cocoon_break", cocoon.tile, radius = 10) + cocoon.anim("kalphite_cocoon_break") + val direction = when (cocoon.rotation) { + 1 -> Direction.NORTH + 2 -> Direction.EAST + 3 -> Direction.SOUTH + else -> Direction.WEST + } + val npc = NPCs.add("kalphite_worker", cocoon.tile.add(direction), direction) + if (source is Player) { + npc.interactPlayer(source, "Attack") + } + softQueue("cocoon_respawn", 10) { + cocoon.anim("kalphite_cocoon_return") + } + softQueue("cocoon_idle", 12) { + cocoon.anim("kalphite_cocoon_idle") + } + return + } + } +} diff --git a/game/src/main/kotlin/content/area/kharidian_desert/kalphite_lair/WeirdOldMan.kt b/game/src/main/kotlin/content/area/kharidian_desert/kalphite_lair/WeirdOldMan.kt new file mode 100644 index 0000000000..d38c4a7107 --- /dev/null +++ b/game/src/main/kotlin/content/area/kharidian_desert/kalphite_lair/WeirdOldMan.kt @@ -0,0 +1,49 @@ +package content.area.kharidian_desert.kalphite_lair + +import content.entity.player.dialogue.Confused +import content.entity.player.dialogue.Happy +import content.entity.player.dialogue.Laugh +import content.entity.player.dialogue.Neutral +import content.entity.player.dialogue.Quiz +import content.entity.player.dialogue.Scared +import content.entity.player.dialogue.Shifty +import content.entity.player.dialogue.Shock +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.entity.character.player.Player +import world.gregs.voidps.type.random + +class WeirdOldMan : Script { + init { + npcOperate("Talk-to", "weird_old_man") { + when (random.nextInt(3)) { + 0 -> { + npc("Pst, wanna hear a secret?") + choice { + option("Sure!") { + npc("They've got six legs... SIX!") + } + option("No thanks.") + } + } + 1 -> aaa() + 2 -> { + npc("She likes to be tickled hehehehe.") + player("Okay...") + } + } + } + } + + private suspend fun Player.aaa() { + npc("AAAAAAAAARRRRRRGGGGGHHHHHHHH!") + choice { + option("What's wrong?") { + aaa() + } + option("I'll leave you to it then...") + } + } +} diff --git a/game/src/main/kotlin/content/area/misthalin/lumbridge/combat_hall/CombatDummy.kt b/game/src/main/kotlin/content/area/misthalin/lumbridge/combat_hall/CombatDummy.kt index 6903b57cef..ba57f97509 100644 --- a/game/src/main/kotlin/content/area/misthalin/lumbridge/combat_hall/CombatDummy.kt +++ b/game/src/main/kotlin/content/area/misthalin/lumbridge/combat_hall/CombatDummy.kt @@ -21,12 +21,12 @@ class CombatDummy : Script { } combatPrepare { target -> - when { - target is NPC && target.id == "magic_dummy" && fightStyle != "magic" -> { + when (target) { + is NPC if target.id == "magic_dummy" && fightStyle != "magic" -> { message("You can only use Magic against this dummy.") false } - target is NPC && target.id == "melee_dummy" && fightStyle != "melee" -> { + is NPC if target.id == "melee_dummy" && fightStyle != "melee" -> { message("You can only use Melee against this dummy.") false } diff --git a/game/src/main/kotlin/content/entity/combat/Target.kt b/game/src/main/kotlin/content/entity/combat/Target.kt index 7e3b50902e..84b63bd60d 100644 --- a/game/src/main/kotlin/content/entity/combat/Target.kt +++ b/game/src/main/kotlin/content/entity/combat/Target.kt @@ -16,6 +16,7 @@ import world.gregs.voidps.engine.client.message import world.gregs.voidps.engine.client.variable.hasClock import world.gregs.voidps.engine.data.definition.NPCDefinitions import world.gregs.voidps.engine.entity.character.Character +import world.gregs.voidps.engine.entity.character.mode.PauseMode import world.gregs.voidps.engine.entity.character.mode.combat.CombatMovement import world.gregs.voidps.engine.entity.character.mode.interact.InteractOption import world.gregs.voidps.engine.entity.character.npc.NPC @@ -40,6 +41,9 @@ object Target { } else if (target.def.options[1] != "Attack") { return false } + if (target.mode == PauseMode) { + return false + } if (target.index == -1) { return false } diff --git a/game/src/main/kotlin/content/entity/death/CharacterDeath.kt b/game/src/main/kotlin/content/entity/death/CharacterDeath.kt index 0d3e60c3a8..629e255281 100644 --- a/game/src/main/kotlin/content/entity/death/CharacterDeath.kt +++ b/game/src/main/kotlin/content/entity/death/CharacterDeath.kt @@ -14,7 +14,7 @@ class CharacterDeath : Script { } npcLevelChanged(Skill.Constitution) { _, _, to -> - if (to <= 0 && !queue.contains("death")) { + if (to <= 0 && !queue.contains("death") && Death.canDie(this)) { Death.killed(this) } } diff --git a/game/src/main/kotlin/content/entity/death/NPCDeath.kt b/game/src/main/kotlin/content/entity/death/NPCDeath.kt index eef288de08..0bf2753eca 100644 --- a/game/src/main/kotlin/content/entity/death/NPCDeath.kt +++ b/game/src/main/kotlin/content/entity/death/NPCDeath.kt @@ -14,6 +14,7 @@ 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 @@ -59,10 +60,12 @@ class NPCDeath( val killer = killer val tile = tile npc["death_tile"] = tile - val definition = combatDefinitions.get(npc.def["combat_def", npc.id]) - val ticks = anim(definition.deathAnim) - if (definition.deathSound != null) { - (killer as? Player)?.sound(definition.deathSound!!.id) + 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 ticks = anim(combat.deathAnim) + if (combat.deathSound != null) { + (killer as? Player)?.sound(combat.deathSound!!.id) } delay(if (ticks <= 0) 4 else ticks) if (killer is Player) { @@ -112,9 +115,16 @@ class NPCDeath( if (npc.inMultiCombat && killer is Player && killer["loot_share", false]) { shareLoot(killer, npc, tile, drops) } else { - drops.forEach { item -> - if (!item.id.contains("clue_scroll") && item.amount > 0) { - FloorItems.add(tile, item.id, item.amount, charges = item.charges(), revealTicks = if (item.tradeable) 60 else FloorItems.NEVER, disappearTicks = 120, owner = if (killer is Player) killer else null) + for (item in drops) { + if (item.id.contains("clue_scroll") || item.amount <= 0) { + continue + } + if (item.def.stackable == 0 && item.amount > 1) { + for (i in 0 until item.amount) { + FloorItems.add(tile, item.id, 1, charges = item.charges(), revealTicks = if (item.tradeable) 60 else FloorItems.NEVER, disappearTicks = 120, owner = killer as? Player) + } + } else { + FloorItems.add(tile, item.id, item.amount, charges = item.charges(), revealTicks = if (item.tradeable) 60 else FloorItems.NEVER, disappearTicks = 120, owner = killer as? Player) } } } diff --git a/game/src/main/kotlin/content/entity/effect/toxin/Poison.kt b/game/src/main/kotlin/content/entity/effect/toxin/Poison.kt index 2ad0411fac..9822b82713 100644 --- a/game/src/main/kotlin/content/entity/effect/toxin/Poison.kt +++ b/game/src/main/kotlin/content/entity/effect/toxin/Poison.kt @@ -6,11 +6,14 @@ import content.entity.combat.hit.directHit import content.skill.ranged.ammo import world.gregs.voidps.engine.Script import world.gregs.voidps.engine.client.message +import world.gregs.voidps.engine.client.ui.InterfaceApi +import world.gregs.voidps.engine.client.ui.InterfaceOption import world.gregs.voidps.engine.entity.character.Character import world.gregs.voidps.engine.entity.character.mode.combat.CombatAttack import world.gregs.voidps.engine.entity.character.npc.NPC import world.gregs.voidps.engine.entity.character.player.Player import world.gregs.voidps.engine.entity.character.player.equip.equipped +import world.gregs.voidps.engine.inv.inventory import world.gregs.voidps.engine.timer.* import world.gregs.voidps.network.login.protocol.visual.update.player.EquipSlot import world.gregs.voidps.type.random @@ -60,7 +63,6 @@ fun Player.antiPoison(duration: Int, timeUnit: TimeUnit) { class Poison : Script { init { - // TODO Cure:health_orb:poison playerSpawn { if (poisonDamage != 0) { timers.restart("poison") @@ -79,6 +81,26 @@ class Poison : Script { npcTimerTick("poison", ::tick) timerStop("poison", ::stop) npcTimerStop("poison", ::stop) + + interfaceOption("Use Cure", "health_orb:poison") { + for (type in listOf("antipoison", "super_antipoison", "antipoison+")) { + val index = inventory.items.indexOfFirst { it.id.startsWith(type) } + if (index != -1) { + val option = "Drink" + val item = inventory[index] + InterfaceApi.option(this, InterfaceOption(item, index, option, item.def.options.indexOf(option), "inventory:inventory")) + return@interfaceOption + } + } + val index = inventory.indexOf("prayer_book") + if (index != -1) { + val option = "Recite-prayer" + val item = inventory[index] + InterfaceApi.option(this, InterfaceOption(item, index, option, item.def.options.indexOf(option), "inventory:inventory")) + return@interfaceOption + } + message("You don't have anything to cure the poison.") + } } fun start(character: Character, restart: Boolean): Int { diff --git a/game/src/main/kotlin/content/entity/npc/combat/Attack.kt b/game/src/main/kotlin/content/entity/npc/combat/Attack.kt index b8a98bec3f..ab183c4d7c 100644 --- a/game/src/main/kotlin/content/entity/npc/combat/Attack.kt +++ b/game/src/main/kotlin/content/entity/npc/combat/Attack.kt @@ -41,9 +41,9 @@ class Attack( npcCombatSwing { primaryTarget -> val defId = if (primaryTarget is Player) { val def = def(primaryTarget) - def["combat_def", def.stringId] + def["combat_def", get("transform_id", def.stringId)] } else { - id + get("transform_id", id) } val definition = definitions.getOrNull(defId) ?: return@npcCombatSwing if (definition.attacks.isEmpty()) { diff --git a/game/src/main/kotlin/content/skill/melee/Block.kt b/game/src/main/kotlin/content/skill/melee/Block.kt index f132b25c34..3e86acf391 100644 --- a/game/src/main/kotlin/content/skill/melee/Block.kt +++ b/game/src/main/kotlin/content/skill/melee/Block.kt @@ -5,6 +5,7 @@ import world.gregs.voidps.cache.definition.Params import world.gregs.voidps.engine.Script import world.gregs.voidps.engine.data.definition.AnimationDefinitions import world.gregs.voidps.engine.data.definition.CombatDefinitions +import world.gregs.voidps.engine.data.definition.NPCDefinitions import world.gregs.voidps.engine.data.definition.WeaponAnimationDefinitions import world.gregs.voidps.engine.data.definition.WeaponStyleDefinitions import world.gregs.voidps.engine.entity.character.Character @@ -55,9 +56,10 @@ class Block( } } else if (target is NPC) { val id = if (source is Player) target.def(source).stringId else target.id - val definition = combatDefinitions.get(target.def["combat_def", id]) - target.anim(definition.defendAnim, delay) - source.sound(definition.defendSound?.id ?: return, delay) + val def = NPCDefinitions.get(id) + val combat = combatDefinitions.get(def["combat_def", id]) + target.anim(combat.defendAnim, delay) + source.sound(combat.defendSound?.id ?: return, delay) } } 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 050f1046ab..23363d5f56 100644 --- a/game/src/main/kotlin/content/skill/melee/weapon/Weapon.kt +++ b/game/src/main/kotlin/content/skill/melee/weapon/Weapon.kt @@ -74,6 +74,8 @@ object Weapon { return true } else if (type == "range" && source is NPC && target is Player && source.id.startsWith("thrower_troll") && target.equipped(EquipSlot.Shield).id != "fremennik_round_shield") { return true + } else if ((type == "range" || type == "magic") && source is NPC && source.id == "kalphite_queen") { + return true } return false } diff --git a/game/src/main/kotlin/content/skill/prayer/PrayerConfigs.kt b/game/src/main/kotlin/content/skill/prayer/PrayerConfigs.kt index 75c154c60d..948b39524f 100644 --- a/game/src/main/kotlin/content/skill/prayer/PrayerConfigs.kt +++ b/game/src/main/kotlin/content/skill/prayer/PrayerConfigs.kt @@ -18,10 +18,9 @@ object PrayerConfigs { const val QUICK_CURSES = "quick_curses" } -fun Character.praying(name: String): Boolean = if (this is Player) { - containsVarbit(getActivePrayerVarKey(), name) -} else { - false +fun Character.praying(name: String): Boolean = when (this) { + is Player -> containsVarbit(getActivePrayerVarKey(), name) + else -> false } fun Player.getActivePrayerVarKey(): String = if (isCurses()) PrayerConfigs.ACTIVE_CURSES else PrayerConfigs.ACTIVE_PRAYERS