diff --git a/data/definitions/animations.yml b/data/definitions/animations.yml index bcc4fc9899..c34c374f30 100644 --- a/data/definitions/animations.yml +++ b/data/definitions/animations.yml @@ -1383,27 +1383,27 @@ teleport_land_ectophial: empty_ectophial: id: 9609 ticks: 4 -cow_hit: 5850 +cow_defend: 5850 cow_death: 5851 cow_attack: 5849 cow_eat_grass: 5854 -calf_hit: 150 +calf_defend: 150 calf_death: 244 calf_attack: 245 chicken_attack: 5387 -chicken_hit: 5388 +chicken_defend: 5388 chicken_death: 5389 goblin_attack: 6184 -goblin_hit: 6183 +goblin_defend: 6183 goblin_death: 6182 giant_spider_attack: 5327 -giant_spider_hit: 5328 +giant_spider_defend: 5328 giant_spider_death: 5329 rat_attack: 2705 -rat_hit: 2706 +rat_defend: 2706 giant_rat_attack: 14859 giant_rat_death: 14860 -giant_rat_hit: 14861 +giant_rat_defend: 14861 human_death: 836 sap: 12569 leech: 12575 @@ -1413,39 +1413,39 @@ hand_cannon_special: 12174 hand_cannon_explode: 12175 guthans_spear_attack: 2080 guthans_spear_swipe: 2081 -guthans_spear_block: 12008 +guthans_spear_defend: 12008 veracs_flail_attack: 2062 -veracs_flail_block: 2063 +veracs_flail_defend: 2063 torags_hammers_attack: 2068 dharoks_greataxe_attack: 2066 dharoks_greataxe_smash: 2067 -dharoks_greataxe_block: 2063 +dharoks_greataxe_defend: 2063 boxing_gloves_attack: 3678 -boxing_gloves_block: 3679 +boxing_gloves_defend: 3679 anchor_attack: 5865 -anchor_block: 5866 +anchor_defend: 5866 granite_maul_attack: 1665 granite_maul_block: 1666 godsword_chop: 11978 godsword_slash: 11979 godsword_smash: 11980 godsword_block: 11981 -godsword_hit: 12022 +godsword_defend: 12022 zamorakian_spear_pound: 12005 zamorakian_spear_swipe: 12006 zamorakian_spear_lunge: 12007 -zamorakian_spear_block: 12008 +zamorakian_spear_defend: 12008 maul_attack: 13691 maul_block: 1666 vestas_longsword_attack: 12311 vestas_longsword_lunge: 12310 -vestas_longsword_block: 388 +vestas_longsword_defend: 388 korasis_sword_chop: 12028 korasis_sword_slash: 12029 -korasis_sword_block: 12030 +korasis_sword_defend: 12030 dragon_dagger_attack: 376 dragon_dagger_slash: 377 -dragon_dagger_block: 403 +dragon_dagger_defend: 403 puncture_special: 1062 defender_block: 4177 book_block: 420 @@ -1479,7 +1479,7 @@ weaken_special: 2890 impale_special: 923 spear_wall_special: 10499 banner_attack: 1428 -banner_hit: 1429 +banner_defend: 1429 mouse_toy_attack: 1658 power_of_light_special: 12804 wind_spell: 10546 @@ -1568,7 +1568,7 @@ demon_slayer_cupboard_disappear: 4600 traiborn_bone_spell: 4602 summon_demon: 4617 demon_attack: 64 -demon_hit: 65 +demon_defend: 65 delrith_continue: 4620 delrith_appear: 4623 delrith_death: 4624 @@ -1597,94 +1597,94 @@ bind_runes: 791 unarmed_punch: 422 unarmed_kick: 423 unarmed_block: 422 -unarmed_hit: 424 +unarmed_defend: 424 human_attack: 422 human_block: 422 -human_hit: 424 +human_defend: 424 staff_bash: 419 staff_pound: 419 staff_focus: 419 -staff_hit: 420 +staff_defend: 420 axe_chop: 395 axe_hack: 395 axe_smash: 401 axe_block: 395 -axe_hit: 397 +axe_defend: 397 sceptre_bash: 414 sceptre_pound: 414 sceptre_block: 414 -sceptre_hit: 430 +sceptre_defend: 430 pickaxe_spike: 401 pickaxe_impale: 401 pickaxe_smash: 400 pickaxe_block: 401 -pickaxe_hit: 397 +pickaxe_defend: 397 dagger_stab: 386 dagger_lunge: 386 dagger_slash: 390 dagger_block: 386 -dagger_hit: 388 +dagger_defend: 388 sword_chop: 390 sword_slash: 390 sword_lunge: 386 sword_block: 390 -sword_hit: 388 +sword_defend: 388 2h_chop: 7041 2h_slash: 7041 2h_smash: 7042 2h_block: 7041 -2h_hit: 7050 +2h_defend: 7050 mace_pound: 401 mace_pummel: 401 mace_spike: 400 mace_block: 401 -mace_hit: 403 +mace_defend: 403 claws_chop: 393 claws_slash: 393 claws_lunge: 1067 claws_block: 393 -claws_hit: 397 +claws_defend: 397 hammer_pound: 401 hammer_pummel: 401 hammer_block: 401 -hammer_hit: 403 +hammer_defend: 403 whip_flick: 11968 # needs verification whip_lash: 11969 # needs verification whip_deflect: 11970 # needs verification energy_drain_special: 11971 # needs verification -whip_block: 11974 # needs verification +whip_defend: 11974 # needs verification fun_pound: 400 fun_pummel: 400 fun_block: 400 -fun_hit: 424 +fun_defend: 424 pie_accurate: 2779 pie_rapid: 2779 pie_long_range: 2779 -pie_hit: 3176 +pie_defend: 3176 spear_lunge: 428 spear_swipe: 440 spear_pound: 428 spear_block: 429 -spear_hit: 430 +spear_defend: 430 halberd_jab: 428 halberd_swipe: 440 halberd_fend: 428 -halberd_hit: 430 +halberd_defend: 430 bow_accurate: 426 bow_rapid: 426 bow_long_range: 426 -bow_hit: 424 +bow_defend: 424 snapshot_special: 1074 crossbow_accurate: 4230 crossbow_rapid: 4230 crossbow_long_range: 4230 -crossbow_hit: 424 +crossbow_defend: 424 karils_crossbow_shoot: 2075 zaniks_crossbow_special: 11359 thrown_accurate: 929 thrown_rapid: 929 thrown_long_range: 929 -thrown_hit: 424 +thrown_defend: 424 throw_dart: 582 toktz_xil_ul: 3353 throw_javelin: 10501 @@ -1694,37 +1694,37 @@ throw_morrigans_throwing_axe_special: 10504 chinchompa_short_fuse: 2779 chinchompa_medium_fuse: 2779 chinchompa_long_fuse: 2779 -chinchompa_hit: 3176 +chinchompa_defend: 3176 fixed_device_aim_and_fire: -1 # needs verification salamander_scorch: 5247 -salamander_hit: 388 +salamander_defend: 388 scythe_reap: 440 scythe_chop: 440 scythe_jab: 438 scythe_block: 440 -scythe_hit: 435 +scythe_defend: 435 ivandis_flail_slash: 9047 ivandis_flail_crush: 9047 -ivandis_flail_hit: 9048 +ivandis_flail_defend: 9048 sling_rock: 14867 # needs verification sling_sling: 14867 # needs verification sling_chuck: 14867 # needs verification sling_lob: 14867 # needs verification -#sling_hit: -1 +#sling_defend: -1 trident_jab: -1 # needs verification trident_swipe: -1 # needs verification trident_fend: -1 # needs verification -trident_hit: -1 # needs verification +trident_defend: -1 # needs verification staff_of_light_jab: 15072 staff_of_light_swipe: 15071 staff_of_light_fend: 414 -staff_of_light_hit: 12806 +staff_of_light_defend: 12806 chaotic_maul_attack: 13055 -chaotic_maul_block: 13054 +chaotic_maul_defend: 13054 pull_lever: 2140 dragon_breath: 81 dragon_attack: 91 -dragon_hit: 89 +dragon_defend: 89 dragon_death: 92 teleport_jewellery: id: 9603 @@ -1769,7 +1769,7 @@ fletching_string_rune_crossbow: 6677 dig_with_spade: 830 giant_mole_burrow: 3314 giant_mole_attack: 3312 -giant_mole_hit: 3311 +giant_mole_defend: 3311 giant_mole_death: 3310 dirt_projectile: 570 giant_mole_burrow_up: 1664 @@ -1780,19 +1780,19 @@ stomp_eyes: 794 abyss_kneel: 1331 abyss_stand: 1332 crawling_cave: 844 -abyssal_leech_hit: 2182 +abyssal_leech_defend: 2182 abyssal_leech_attack: 2181 abyssal_leech_death: 2183 -abyssal_guardian_hit: 2188 +abyssal_guardian_defend: 2188 abyssal_guardian_attack: 2186 abyssal_guardian_death: 2189 -abyssal_walker_hit: 2192 +abyssal_walker_defend: 2192 abyssal_walker_attack: 2193 abyssal_walker_death: 2194 -gecko_hit: 7208 +gecko_defend: 7208 gecko_attack: 7207 gecko_death: 7205 -wolves_hit: 6557 +wolves_defend: 6557 wolves_attack: 6559 wolves_death: 6558 run_replenish: 9988 @@ -1838,7 +1838,7 @@ fall_off_log_right: 2582 fall_on_floor: 767 stepping_stone_step: 769 stepping_stone_jump: 741 -skeleton_hit: 5489 +skeleton_defend: 5489 skeleton_death: 5491 skeleton_crush: 5485 skeleton_slash: 5487 diff --git a/data/definitions/graphics.yml b/data/definitions/graphics.yml index 82d6f6c3be..ef56ec2820 100644 --- a/data/definitions/graphics.yml +++ b/data/definitions/graphics.yml @@ -4,7 +4,7 @@ demon_slayer_spell: id: 782 height: 0 flight_time: [ -1, -1, 30, 30 ] -demon_slayer_spell_hit: 783 +demon_slayer_spell_impact: 783 silverlight_sparkle: 778 toss_water: 779 possessed_pickaxe: 309 @@ -545,7 +545,7 @@ soul_split: id: 2263 curve: 15 flight_time: [ 20, 30, 40, 50, 60, 70, 80, 90, 100, 110 ] -soul_split_hit: 2264 +soul_split_impact: 2264 cast_leech_energy: 2251 proj_leech_energy: id: 2252 @@ -613,8 +613,8 @@ zaryte_arrow: height: 3 curve: 15 flight_time: [ 10, 15, 20, 25, 30, 35, 40, 45, 50, 55 ] -descent_of_darkness_hit: 1103 -descent_of_dragons_hit: 1100 +descent_of_darkness_impact: 1103 +descent_of_dragons_impact: 1100 snipe_special: id: 698 delay: 41 @@ -637,10 +637,10 @@ seercull_special_arrow: height: 3 curve: 15 flight_time: [ 10, 15, 20, 25, 30, 35, 40 ] -seercull_special_hit: 474 -zamorak_bow_special_hit: 127 -saradomin_bow_special_hit: 128 -guthix_bow_special_hit: 129 +seercull_special_impact: 474 +zamorak_bow_special_impact: 127 +saradomin_bow_special_impact: 128 +guthix_bow_special_impact: 129 saradomin_bow_restoration: 93 bronze_dart_throw: id: 1234 @@ -910,7 +910,7 @@ red_chinchompa: height: 5 curve: 15 flight_time: [ 16, 21, 26, 31, 36, 41, 46, 51, 56, 61 ] -chinchompa_hit: +chinchompa_impact: id: 2739 height: 50 rune_throwing_axe_special_throw: @@ -921,7 +921,7 @@ rune_throwing_axe_special: delay: 41 curve: 0 flight_time: [ 10, 15, 20, 25, 30 ] -energy_drain_hit: +energy_drain_impact: id: 2108 height: 60 smash_special: 1840 @@ -941,7 +941,7 @@ sanctuary_special: 247 sever_special: id: 2118 height: 60 -saradomins_lightning_hit: 1194 +saradomins_lightning_impact: 1194 favour_of_the_war_god_special: 1052 liquify_special: id: 1048 @@ -951,7 +951,7 @@ sunder_special: 1027 warstrike_special: 2114 healing_blade_special: 2109 ice_cleave_special: 1221 -ice_cleave_hit: 2104 +ice_cleave_impact: 2104 sweep_special: id: 282 height: 60 @@ -959,27 +959,27 @@ powerstab_special: 1225 shove_special: id: 253 height: 60 -shove_hit: 254 +dragon_spear_stun: 254 quick_smash_special: id: 340 height: 60 clobber_special: 479 disrupt_special: 1729 -disrupt_hit: 1730 +disrupt_impact: 1730 weaken_special: 483 impale_special: id: 274 height: 60 spear_wall_special: 1835 power_of_light_special: 2319 -power_of_light_hit: 2320 +power_of_light_impact: 2320 wind_spell_cast: 457 wind_rush: id: 458 delay: 51 height: -4 flight_time: [ 5, 15, 25, 35, 45, 55, 65, 75, 85, 95 ] -wind_rush_hit: +wind_rush_impact: id: 463 height: 60 wind_strike: @@ -987,7 +987,7 @@ wind_strike: delay: 51 height: -4 flight_time: [ 5, 15, 25, 35, 45, 55, 65, 75, 85, 95 ] -wind_strike_hit: +wind_strike_impact: id: 463 height: 60 wind_bolt: @@ -995,7 +995,7 @@ wind_bolt: delay: 51 height: -4 flight_time: [ 5, 15, 25, 35, 45, 55, 65, 75, 85, 95 ] -wind_bolt_hit: +wind_bolt_impact: id: 464 height: 60 wind_blast: @@ -1003,7 +1003,7 @@ wind_blast: delay: 51 height: -4 flight_time: [ 5, 15, 25, 35, 45, 55, 65, 75, 85, 95 ] -wind_blast_hit: +wind_blast_impact: id: 1863 height: 60 wind_wave: @@ -1011,7 +1011,7 @@ wind_wave: delay: 51 height: -4 flight_time: [ 5, 15, 25, 35, 45, 55, 65, 75, 85, 95 ] -wind_wave_hit: +wind_wave_impact: id: 2699 height: 60 wind_surge: @@ -1019,7 +1019,7 @@ wind_surge: delay: 51 height: -4 flight_time: [ 5, 15, 25, 35, 45, 55, 65, 75, 85, 95 ] -wind_surge_hit: +wind_surge_impact: id: 2700 height: 60 water_spell_cast: 2701 @@ -1029,7 +1029,7 @@ water_strike: delay: 51 height: -4 flight_time: [ 5, 15, 25, 35, 45, 55, 65, 75, 85, 95 ] -water_strike_hit: +water_strike_impact: id: 2708 height: 60 water_bolt: @@ -1037,7 +1037,7 @@ water_bolt: delay: 51 height: -4 flight_time: [ 5, 15, 25, 35, 45, 55, 65, 75, 85, 95 ] -water_bolt_hit: +water_bolt_impact: id: 2709 height: 60 water_blast: @@ -1045,7 +1045,7 @@ water_blast: delay: 51 height: -4 flight_time: [ 5, 15, 25, 35, 45, 55, 65, 75, 85, 95 ] -water_blast_hit: +water_blast_impact: id: 2710 height: 60 water_wave: @@ -1053,7 +1053,7 @@ water_wave: delay: 51 height: -4 flight_time: [ 5, 15, 25, 35, 45, 55, 65, 75, 85, 95 ] -water_wave_hit: +water_wave_impact: id: 2711 height: 60 water_surge: @@ -1061,7 +1061,7 @@ water_surge: delay: 51 height: -4 flight_time: [ 5, 15, 25, 35, 45, 55, 65, 75, 85, 95 ] -water_surge_hit: +water_surge_impact: id: 2711 height: 60 earth_strike_cast: 2713 @@ -1070,7 +1070,7 @@ earth_strike: delay: 51 height: -4 flight_time: [ 5, 15, 25, 35, 45, 55, 65, 75, 85, 95 ] -earth_strike_hit: +earth_strike_impact: id: 2723 height: 60 earth_bolt_cast: 2714 @@ -1079,7 +1079,7 @@ earth_bolt: delay: 51 height: -4 flight_time: [ 5, 15, 25, 35, 45, 55, 65, 75, 85, 95 ] -earth_bolt_hit: +earth_bolt_impact: id: 2724 height: 60 earth_blast_cast: 2715 @@ -1088,7 +1088,7 @@ earth_blast: delay: 51 height: -4 flight_time: [ 5, 15, 25, 35, 45, 55, 65, 75, 85, 95 ] -earth_blast_hit: +earth_blast_impact: id: 2725 height: 60 earth_wave_cast: 2716 @@ -1097,7 +1097,7 @@ earth_wave: delay: 51 height: -4 flight_time: [ 5, 15, 25, 35, 45, 55, 65, 75, 85, 95 ] -earth_wave_hit: +earth_wave_impact: id: 2726 height: 60 earth_surge_cast: 2717 @@ -1106,7 +1106,7 @@ earth_surge: delay: 51 height: -4 flight_time: [ 5, 15, 25, 35, 45, 55, 65, 75, 85, 95 ] -earth_surge_hit: +earth_surge_impact: id: 2727 height: 60 fire_spell_cast: 2728 @@ -1115,7 +1115,7 @@ fire_strike: delay: 51 height: -4 flight_time: [ 5, 15, 25, 35, 45, 55, 65, 75, 85, 95 ] -fire_strike_hit: +fire_strike_impact: id: 2737 height: 60 fire_bolt: @@ -1123,7 +1123,7 @@ fire_bolt: delay: 51 height: -4 flight_time: [ 5, 15, 25, 35, 45, 55, 65, 75, 85, 95 ] -fire_bolt_hit: +fire_bolt_impact: id: 2738 height: 60 fire_blast_1: @@ -1136,7 +1136,7 @@ fire_blast_2: delay: 51 height: -4 flight_time: [ 5, 15, 25, 35, 45, 55, 65, 75, 85, 95 ] -fire_blast_hit: +fire_blast_impact: id: 2739 height: 60 fire_wave_1: @@ -1149,7 +1149,7 @@ fire_wave_2: delay: 51 height: -4 flight_time: [ 5, 15, 25, 35, 45, 55, 65, 75, 85, 95 ] -fire_wave_hit: +fire_wave_impact: id: 2740 height: 60 fire_surge_1: @@ -1162,7 +1162,7 @@ fire_surge_2: delay: 51 height: -4 flight_time: [ 5, 15, 25, 35, 45, 55, 65, 75, 85, 95 ] -fire_surge_hit: +fire_surge_impact: id: 2741 height: 60 crumble_undead_cast: @@ -1175,7 +1175,7 @@ crumble_undead: end_height: 4 curve: 16 flight_time: [ 5, 10, 15, 20, 25, 30, 35 ] -crumble_undead_hit: +crumble_undead_impact: id: 147 height: 60 iban_blast_cast: @@ -1189,7 +1189,7 @@ iban_blast: offset: 1 curve: 16 flight_time: [ -1, 6, 16, 26, 36, 46, 56, 66, 76, 86 ] -iban_blast_hit: +iban_blast_impact: id: 89 height: 60 magic_dart_cast: @@ -1203,16 +1203,16 @@ magic_dart: curve: 16 offset: 1 flight_time: [ 5, 15, 25, 35, 45, 55, 65, 75, 85, 95 ] -magic_dart_hit: +magic_dart_impact: id: 329 height: 60 -saradomin_strike_hit: +saradomin_strike_impact: id: 76 height: 60 -claws_of_guthix_hit: +claws_of_guthix_impact: id: 77 height: 60 -flames_of_zamorak_hit: +flames_of_zamorak_impact: id: 78 height: 60 confuse_cast: @@ -1224,7 +1224,7 @@ confuse: height: 3 curve: 16 flight_time: [ -1, 5, 15, 25, 35, 45, 55, 65, 75, 85 ] -confuse_hit: +confuse_impact: id: 104 height: 60 weaken_cast: @@ -1237,7 +1237,7 @@ weaken: end_height: -2 curve: 16 flight_time: [ 12, 22, 32, 42, 52, 62, 72, 82, 92, 102 ] -weaken_hit: +weaken_impact: id: 107 height: 60 curse_cast: @@ -1249,7 +1249,7 @@ curse: height: 4 curve: 16 flight_time: [ 5, 15, 25, 35, 45, 55, 65, 75, 85, 95 ] -curse_hit: +curse_impact: id: 110 height: 60 bind_cast: @@ -1261,13 +1261,13 @@ bind: height: 4 curve: 16 flight_time: [ -1, -1, 1, 11, 21, 31, 41, 51, 61, 71 ] -bind_hit: +bind_impact: id: 181 height: 60 -snare_hit: +snare_impact: id: 180 height: 60 -entangle_hit: +entangle_impact: id: 179 height: 60 vulnerability_cast: @@ -1279,7 +1279,7 @@ vulnerability: height: 4 curve: 16 flight_time: [ 22, 32, 42, 52, 62, 72, 82, 92, 102, 112 ] -vulnerability_hit: +vulnerability_impact: id: 169 height: 60 enfeeble_cast: @@ -1291,7 +1291,7 @@ enfeeble: end_height: -4 curve: 16 flight_time: [ 8, 18, 28, 38, 48, 58, 68, 78, 88, 98 ] -enfeeble_hit: +enfeeble_impact: id: 172 height: 60 stun_cast: @@ -1304,7 +1304,7 @@ stun: end_height: 4 curve: 16 flight_time: [ 4, 14, 24, 34, 44, 54, 64, 74, 84, 94 ] -stun_hit: +stun_impact: id: 348 height: 60 stun_long: @@ -1317,7 +1317,7 @@ teleport_block: end_height: -4 curve: 16 flight_time: [ 5, 15, 25, 35, 45, 55, 65, 75, 85, 95 ] -teleport_block_hit: +teleport_block_impact: id: 1843 height: 60 smoke_rush: @@ -1325,75 +1325,75 @@ smoke_rush: delay: 51 curve: 16 flight_time: [ 5, 15, 25, 35, 45, 55, 65, 75, 85, 95 ] -smoke_rush_hit: 385 -smoke_burst_hit: 389 +smoke_rush_impact: 385 +smoke_burst_impact: 389 smoke_blitz: id: 386 delay: 51 curve: 16 flight_time: [ 5, 15, 25, 35, 45, 55, 65, 75, 85, 95 ] -smoke_blitz_hit: 387 -smoke_barrage_hit: 391 +smoke_blitz_impact: 387 +smoke_barrage_impact: 391 shadow_rush: id: 378 delay: 51 curve: 16 flight_time: [ 5, 15, 25, 35, 45, 55, 65, 75, 85, 95 ] -shadow_rush_hit: 379 -shadow_burst_hit: 382 +shadow_rush_impact: 379 +shadow_burst_impact: 382 shadow_blitz: id: 380 delay: 51 curve: 16 flight_time: [ 5, 15, 25, 35, 45, 55, 65, 75, 85, 95 ] -shadow_blitz_hit: 381 -shadow_barrage_hit: 383 +shadow_blitz_impact: 381 +shadow_barrage_impact: 383 blood_rush: id: 372 delay: 51 curve: 16 flight_time: [ 5, 15, 25, 35, 45, 55, 65, 75, 85, 95 ] -blood_rush_hit: 373 -blood_burst_hit: 376 +blood_rush_impact: 373 +blood_burst_impact: 376 blood_blitz: id: 375 delay: 51 curve: 16 flight_time: [ 5, 15, 25, 35, 45, 55, 65, 75, 85, 95 ] -blood_blitz_hit: 374 -blood_barrage_hit: 377 +blood_blitz_impact: 374 +blood_barrage_impact: 377 ice_rush: id: 360 delay: 51 curve: 16 flight_time: [ 5, 15, 25, 35, 45, 55, 65, 75, 85, 95 ] -ice_rush_hit: 361 -ice_burst_hit: 363 +ice_rush_impact: 361 +ice_burst_impact: 363 ice_blitz: id: 368 delay: 51 curve: 16 flight_time: [ 5, 15, 25, 35, 45, 55, 65, 75, 85, 95 ] -ice_blitz_hit: 367 -ice_barrage_hit: 369 +ice_blitz_impact: 367 +ice_barrage_impact: 369 miasmic_rush_cast: 1845 miasmic_rush: id: 1846 delay: 51 curve: 16 flight_time: [ 5, 15, 25, 35, 45, 55, 65, 75, 85, 95 ] -miasmic_rush_hit: 1847 +miasmic_rush_impact: 1847 miasmic_burst_cast: 1848 -miasmic_burst_hit: 1849 +miasmic_burst_impact: 1849 miasmic_blitz_cast: 1850 miasmic_blitz: id: 1852 delay: 51 curve: 16 flight_time: [ 5, 15, 25, 35, 45, 55, 65, 75, 85, 95 ] -miasmic_blitz_hit: 1851 +miasmic_blitz_impact: 1851 miasmic_barrage_cast: 1853 -miasmic_barrage_hit: 1854 +miasmic_barrage_impact: 1854 bone_offering: 624 vengeance: id: 726 diff --git a/data/definitions/interfaces.yml b/data/definitions/interfaces.yml index adaf63b9c1..009e793c91 100644 --- a/data/definitions/interfaces.yml +++ b/data/definitions/interfaces.yml @@ -1597,64 +1597,64 @@ make_mould_slayer: amulet_unstrung_text: 26 bracelet_text: 30 make_ring: 81 - make_ring_0: 81 - make_ring_options_0: 82 - make_ring_1: 83 - make_ring_options_1: 84 - make_ring_2: 85 - make_ring_options_2: 86 - make_ring_3: 87 - make_ring_options_3: 88 - make_ring_4: 89 - make_ring_options_4: 90 - make_ring_5: 91 - make_ring_options_5: 92 - make_ring_6: 93 - make_ring_options_6: 94 - make_ring_7: 96 - make_ring_options_7: 97 - make_necklace_0: 67 - make_necklace_options_0: 68 - make_necklace_1: 69 - make_necklace_options_1: 70 - make_necklace_2: 71 - make_necklace_options_2: 72 - make_necklace_3: 73 - make_necklace_options_3: 74 - make_necklace_4: 75 - make_necklace_options_4: 76 - make_necklace_5: 77 - make_necklace_options_5: 78 - make_necklace_6: 79 - make_necklace_options_6: 80 - make_amulet_unstrung_0: 52 - make_amulet_unstrung_options_0: 53 - make_amulet_unstrung_1: 54 - make_amulet_unstrung_options_1: 55 - make_amulet_unstrung_2: 56 - make_amulet_unstrung_options_2: 57 - make_amulet_unstrung_3: 58 - make_amulet_unstrung_options_3: 59 - make_amulet_unstrung_4: 60 - make_amulet_unstrung_options_4: 61 - make_amulet_unstrung_5: 62 - make_amulet_unstrung_options_5: 63 - make_amulet_unstrung_6: 64 - make_amulet_unstrung_options_6: 65 - make_bracelet_0: 32 - make_bracelet_options_0: 33 - make_bracelet_1: 34 - make_bracelet_options_1: 35 - make_bracelet_2: 36 - make_bracelet_options_2: 37 - make_bracelet_3: 38 - make_bracelet_options_3: 39 - make_bracelet_4: 40 - make_bracelet_options_4: 41 - make_bracelet_5: 42 - make_bracelet_options_5: 43 - make_bracelet_6: 44 - make_bracelet_options_6: 45 + make_ring_gold: 81 + make_ring_option_gold: 82 + make_ring_sapphire: 83 + make_ring_option_sapphire: 84 + make_ring_emerald: 85 + make_ring_option_emerald: 86 + make_ring_ruby: 87 + make_ring_option_ruby: 88 + make_ring_diamond: 89 + make_ring_option_diamond: 90 + make_ring_dragonstone: 91 + make_ring_option_dragonstone: 92 + make_ring_onyx: 93 + make_ring_option_onyx: 94 + make_ring_enchanted_gem: 96 + make_ring_option_enchanted_gem: 97 + make_necklace_gold: 67 + make_necklace_option_gold: 68 + make_necklace_sapphire: 69 + make_necklace_option_sapphire: 70 + make_necklace_emerald: 71 + make_necklace_option_emerald: 72 + make_necklace_ruby: 73 + make_necklace_option_ruby: 74 + make_necklace_diamond: 75 + make_necklace_option_diamond: 76 + make_necklace_dragonstone: 77 + make_necklace_option_dragonstone: 78 + make_necklace_onyx: 79 + make_necklace_option_onyx: 80 + make_amulet_unstrung_gold: 52 + make_amulet_unstrung_option_gold: 53 + make_amulet_unstrung_sapphire: 54 + make_amulet_unstrung_option_sapphire: 55 + make_amulet_unstrung_emerald: 56 + make_amulet_unstrung_option_emerald: 57 + make_amulet_unstrung_ruby: 58 + make_amulet_unstrung_option_ruby: 59 + make_amulet_unstrung_diamond: 60 + make_amulet_unstrung_option_diamond: 61 + make_amulet_unstrung_dragonstone: 62 + make_amulet_unstrung_option_dragonstone: 63 + make_amulet_unstrung_onyx: 64 + make_amulet_unstrung_option_onyx: 65 + make_bracelet_gold: 32 + make_bracelet_option_gold: 33 + make_bracelet_sapphire: 34 + make_bracelet_option_sapphire: 35 + make_bracelet_emerald: 36 + make_bracelet_option_emerald: 37 + make_bracelet_ruby: 38 + make_bracelet_option_ruby: 39 + make_bracelet_diamond: 40 + make_bracelet_option_diamond: 41 + make_bracelet_dragonstone: 42 + make_bracelet_option_dragonstone: 43 + make_bracelet_onyx: 44 + make_bracelet_option_onyx: 45 item_info: id: 449 type: overlay_tab @@ -2042,62 +2042,62 @@ make_mould: necklace_text: 35 amulet_unstrung_text: 54 bracelet_text: 73 - make_ring_0: 19 - make_ring_options_0: 20 - make_ring_1: 21 - make_ring_options_1: 22 - make_ring_2: 23 - make_ring_options_2: 24 - make_ring_3: 25 - make_ring_options_3: 26 - make_ring_4: 27 - make_ring_options_4: 28 - make_ring_5: 29 - make_ring_options_5: 30 - make_ring_6: 31 - make_ring_options_6: 32 - make_necklace_0: 38 - make_necklace_options_0: 39 - make_necklace_1: 40 - make_necklace_options_1: 41 - make_necklace_2: 42 - make_necklace_options_2: 43 - make_necklace_3: 44 - make_necklace_options_3: 45 - make_necklace_4: 46 - make_necklace_options_4: 47 - make_necklace_5: 48 - make_necklace_options_5: 49 - make_necklace_6: 50 - make_necklace_options_6: 51 - make_amulet_unstrung_0: 57 - make_amulet_unstrung_options_0: 58 - make_amulet_unstrung_1: 59 - make_amulet_unstrung_options_1: 60 - make_amulet_unstrung_2: 61 - make_amulet_unstrung_options_2: 62 - make_amulet_unstrung_3: 63 - make_amulet_unstrung_options_3: 64 - make_amulet_unstrung_4: 65 - make_amulet_unstrung_options_4: 66 - make_amulet_unstrung_5: 67 - make_amulet_unstrung_options_5: 68 - make_amulet_unstrung_6: 69 - make_amulet_unstrung_options_6: 70 - make_bracelet_0: 76 - make_bracelet_options_0: 77 - make_bracelet_1: 78 - make_bracelet_options_1: 79 - make_bracelet_2: 80 - make_bracelet_options_2: 81 - make_bracelet_3: 82 - make_bracelet_options_3: 83 - make_bracelet_4: 84 - make_bracelet_options_4: 85 - make_bracelet_5: 86 - make_bracelet_options_5: 87 - make_bracelet_6: 88 - make_bracelet_options_6: 89 + make_ring_gold: 19 + make_ring_option_gold: 20 + make_ring_sapphire: 21 + make_ring_option_sapphire: 22 + make_ring_emerald: 23 + make_ring_option_emerald: 24 + make_ring_ruby: 25 + make_ring_option_ruby: 26 + make_ring_diamond: 27 + make_ring_option_diamond: 28 + make_ring_dragonstone: 29 + make_ring_option_dragonstone: 30 + make_ring_onyx: 31 + make_ring_option_onyx: 32 + make_necklace_gold: 38 + make_necklace_option_gold: 39 + make_necklace_sapphire: 40 + make_necklace_option_sapphire: 41 + make_necklace_emerald: 42 + make_necklace_option_emerald: 43 + make_necklace_ruby: 44 + make_necklace_option_ruby: 45 + make_necklace_diamond: 46 + make_necklace_option_diamond: 47 + make_necklace_dragonstone: 48 + make_necklace_option_dragonstone: 49 + make_necklace_onyx: 50 + make_necklace_option_onyx: 51 + make_amulet_unstrung_gold: 57 + make_amulet_unstrung_option_gold: 58 + make_amulet_unstrung_sapphire: 59 + make_amulet_unstrung_option_sapphire: 60 + make_amulet_unstrung_emerald: 61 + make_amulet_unstrung_option_emerald: 62 + make_amulet_unstrung_ruby: 63 + make_amulet_unstrung_option_ruby: 64 + make_amulet_unstrung_diamond: 65 + make_amulet_unstrung_option_diamond: 66 + make_amulet_unstrung_dragonstone: 67 + make_amulet_unstrung_option_dragonstone: 68 + make_amulet_unstrung_onyx: 69 + make_amulet_unstrung_option_onyx: 70 + make_bracelet_gold: 76 + make_bracelet_option_gold: 77 + make_bracelet_sapphire: 78 + make_bracelet_option_sapphire: 79 + make_bracelet_emerald: 80 + make_bracelet_option_emerald: 81 + make_bracelet_ruby: 82 + make_bracelet_option_ruby: 83 + make_bracelet_diamond: 84 + make_bracelet_option_diamond: 85 + make_bracelet_dragonstone: 86 + make_bracelet_option_dragonstone: 87 + make_bracelet_onyx: 88 + make_bracelet_option_onyx: 89 warning_death: 676 warning_death2: 677 warning_death3: 678 diff --git a/data/definitions/sounds.yml b/data/definitions/sounds.yml index 54579a7b27..8876ff6c4d 100644 --- a/data/definitions/sounds.yml +++ b/data/definitions/sounds.yml @@ -1,4 +1,4 @@ -demon_hit: 399 +demon_defend: 399 demon_attack: 397 summon_npc: 188 chest_open: 52 @@ -108,28 +108,28 @@ gate_close: 70 gate_open: 71 fell_tree: 2734 drop_item: 2739 -pickup_item: 2582 +take_item: 2582 prayer_drain: 2672 teleport: 200 teleport_land: 201 teleport_tablet: 965 -cow_hit: 371 +cow_defend: 371 cow_death: 370 cow_attack: 369 -calf_hit: 368 +calf_defend: 368 calf_death: 367 calf_attack: 366 -chicken_hit: 357 +chicken_defend: 357 chicken_death: 356 chicken_attack: 355 -goblin_hit: 470 +goblin_defend: 470 goblin_death: 471 goblin_attack: 469 giant_spider_attack: 3605 -giant_spider_hit: 3607 +giant_spider_defend: 3607 giant_spider_death: 3606 rat_attack: 710 -rat_hit: 713 +rat_defend: 713 rat_death: 711 armour_piercing: 2910 blood_forfeit: 2911 @@ -148,13 +148,13 @@ eat: 2393 cut_gem: 2586 glassblowing: 2724 combine_battlestaff: 2585 -human_hit: 14 -male_hit_0: 518 -male_hit_1: 519 -male_hit_2: 520 -male_hit_3: 521 -female_hit_0: 509 -female_hit_1: 510 +human_defend: 14 +male_defend_0: 518 +male_defend_1: 519 +male_defend_2: 520 +male_defend_3: 521 +female_defend_0: 509 +female_defend_1: 510 smelt_bar: 2725 superheat_all: 190 superheat_fail: 191 @@ -178,7 +178,7 @@ powerstab_special: 2530 snipe_special: 1080 sunder_special: 3481 liquify_special: 3473 -god_bow_special_hit: 9513 +god_bow_special_impact: 9513 descent_of_dragons: 3733 descent_of_darkness: 3737 morrigans_javelin_special: 2699 @@ -200,14 +200,14 @@ godwars_godsword_special_attack: 3865 pottery: 2588 giant_mole_burrow_down: 1641 giant_mole_attack: 1642 -giant_mole_hit: 1646 +giant_mole_defend: 1646 giant_mole_burrow: 1643 giant_mole_death: 1645 tele_other_cast: 199 teleport_all: 200 boil_burst: 2711 abyssal_squeezethrough: 2709 -wolves_hit: 912 +wolves_defend: 912 wolves_attack: 909 wolves_death: 911 bigghost_appear: 1595 diff --git a/data/definitions/weapon-animations.yml b/data/definitions/weapon-animations.yml index 7c9e40a0bb..d76dd0719c 100644 --- a/data/definitions/weapon-animations.yml +++ b/data/definitions/weapon-animations.yml @@ -1,28 +1,28 @@ anchor: default: anchor_attack - hit: anchor_block + defend: anchor_defend dragon_dagger: slash: dragon_dagger_slash default: dragon_dagger_attack - hit: dragon_dagger_block + defend: dragon_dagger_defend korasis_sword: chop: korasis_sword_chop default: korasis_sword_slash - hit: korasis_sword_block + defend: korasis_sword_defend vestas_longsword: lunge: vestas_longsword_lunge default: vestas_longsword_attack - hit: vestas_longsword_block + defend: vestas_longsword_defend banner: default: banner_attack - hit: banner_hit + defend: banner_defend boxing_gloves: default: boxing_gloves_attack - hit: boxing_gloves_block + defend: boxing_gloves_defend dharoks_greataxe: smash: dharoks_greataxe_smash default: dharoks_greataxe_attack - hit: dharoks_greataxe_block + defend: dharoks_greataxe_defend easter_carrot: default: easter_carrot_whack godsword: @@ -30,31 +30,31 @@ godsword: pummel: godsword_pummel spike: godsword_spike block: godsword_block - hit: godsword_hit + defend: godsword_defend tzhaar_ket_om: default: tzhaar_ket_om_attack - hit: tzhaar_ket_om_block + defend: tzhaar_ket_om_defend granite_maul: default: granite_maul_attack - hit: granite_maul_block + defend: granite_maul_block guthans_warspear: swipe: guthans_spear_swipe default: guthans_spear_attack - hit: guthans_spear_block + defend: guthans_spear_defend mouse_toy: default: mouse_toy_attack - hit: whip_block + defend: whip_defend torags_hammers: default: torags_hammers_attack veracs_flail: default: veracs_flail_attack - hit: veracs_flail_block + defend: veracs_flail_defend zamorakian_spear: lunge: zamorakian_spear_lunge swipe: zamorakian_spear_swipe pound: zamorakian_spear_pound block: zamorakian_spear_lunge - hit: zamorakian_spear_block + defend: zamorakian_spear_defend chinchompa: default: chinchompa_short_fuse pie: @@ -75,4 +75,4 @@ salamander: default: salamander_scorch chaotic_maul: default: chaotic_maul_attack - hit: chaotic_maul_block \ No newline at end of file + defend: chaotic_maul_defend \ No newline at end of file diff --git a/data/map/teleports.yml b/data/map/teleports.yml index 2a24f31a52..2960875b2f 100644 --- a/data/map/teleports.yml +++ b/data/map/teleports.yml @@ -4590,9 +4590,9 @@ tile: x: 3237 y: 9858 - delta: - x: 1 - y: -6400 + to: + x: 3238 + y: 3458 ######## 13105 ######## - id: 35533 option: Climb-up diff --git a/engine/src/main/kotlin/world/gregs/voidps/engine/entity/item/Item.kt b/engine/src/main/kotlin/world/gregs/voidps/engine/entity/item/Item.kt index ab308b6042..cfe49b4310 100644 --- a/engine/src/main/kotlin/world/gregs/voidps/engine/entity/item/Item.kt +++ b/engine/src/main/kotlin/world/gregs/voidps/engine/entity/item/Item.kt @@ -6,7 +6,7 @@ import world.gregs.voidps.engine.data.definition.ItemDefinitions class Item( val id: String = "", - amount: Int = 0 + amount: Int = 1 ) { internal val value = amount val def: ItemDefinition diff --git a/engine/src/main/kotlin/world/gregs/voidps/engine/entity/item/floor/FloorItemOption.kt b/engine/src/main/kotlin/world/gregs/voidps/engine/entity/item/floor/FloorItemOption.kt index cc34c457a1..c57e50acb2 100644 --- a/engine/src/main/kotlin/world/gregs/voidps/engine/entity/item/floor/FloorItemOption.kt +++ b/engine/src/main/kotlin/world/gregs/voidps/engine/entity/item/floor/FloorItemOption.kt @@ -25,8 +25,8 @@ data class FloorItemOption( } } -fun floorItemOperate(option: String, item: String = "*", arrive: Boolean = true, override: Boolean = true, handler: suspend FloorItemOption.() -> Unit) { - Events.handle>("player_operate_floor_item", option, item, "player", override = override) { +fun floorItemOperate(option: String, item: String = "*", arrive: Boolean = true, handler: suspend FloorItemOption.() -> Unit) { + Events.handle>("player_operate_floor_item", option, item, "player") { if (arrive) { arriveDelay() } @@ -34,14 +34,14 @@ fun floorItemOperate(option: String, item: String = "*", arrive: Boolean = true, } } -fun floorItemApproach(option: String, item: String = "*", override: Boolean = true, handler: suspend FloorItemOption.() -> Unit) { - Events.handle>("player_approach_floor_item", option, item, "player", override = override) { +fun floorItemApproach(option: String, item: String = "*", handler: suspend FloorItemOption.() -> Unit) { + Events.handle>("player_approach_floor_item", option, item, "player") { handler.invoke(this) } } -fun npcOperateFloorItem(option: String, item: String = "*", npc: String = "*", arrive: Boolean = true, override: Boolean = true, handler: suspend FloorItemOption.() -> Unit) { - Events.handle>("npc_operate_floor_item", option, item, npc, override = override) { +fun npcOperateFloorItem(option: String, item: String = "*", npc: String = "*", arrive: Boolean = true, handler: suspend FloorItemOption.() -> Unit) { + Events.handle>("npc_operate_floor_item", option, item, npc) { if (arrive) { arriveDelay() } @@ -49,27 +49,27 @@ fun npcOperateFloorItem(option: String, item: String = "*", npc: String = "*", a } } -fun npcApproachFloorItem(option: String, item: String = "*", npc: String = "*", override: Boolean = true, handler: suspend FloorItemOption.() -> Unit) { - Events.handle>("npc_approach_floor_item", option, item, npc, override = override) { +fun npcApproachFloorItem(option: String, item: String = "*", npc: String = "*", handler: suspend FloorItemOption.() -> Unit) { + Events.handle>("npc_approach_floor_item", option, item, npc) { handler.invoke(this) } } -fun characterOperateFloorItem(option: String, item: String = "*", arrive: Boolean = true, override: Boolean = true, block: suspend FloorItemOption.() -> Unit) { +fun characterOperateFloorItem(option: String, item: String = "*", arrive: Boolean = true, block: suspend FloorItemOption.() -> Unit) { val handler: suspend FloorItemOption.(Character) -> Unit = { if (arrive) { arriveDelay() } block.invoke(this) } - Events.handle("player_operate_floor_item", option, item, "player", override = override, handler = handler) - Events.handle("npc_operate_floor_item", option, item, "*", override = override, handler = handler) + Events.handle("player_operate_floor_item", option, item, "player", handler = handler) + Events.handle("npc_operate_floor_item", option, item, "*", handler = handler) } -fun characterApproachFloorItem(option: String, item: String = "*", override: Boolean = true, block: suspend FloorItemOption.() -> Unit) { +fun characterApproachFloorItem(option: String, item: String = "*", block: suspend FloorItemOption.() -> Unit) { val handler: suspend FloorItemOption.(Character) -> Unit = { block.invoke(this) } - Events.handle("player_approach_floor_item", option, item, "player", override = override, handler = handler) - Events.handle("npc_approach_floor_item", option, item, "*", override = override, handler = handler) + Events.handle("player_approach_floor_item", option, item, "player", handler = handler) + Events.handle("npc_approach_floor_item", option, item, "*", handler = handler) } \ No newline at end of file diff --git a/engine/src/main/kotlin/world/gregs/voidps/engine/queue/ActionPriority.kt b/engine/src/main/kotlin/world/gregs/voidps/engine/queue/ActionPriority.kt index d8a1742597..f32adb7cde 100644 --- a/engine/src/main/kotlin/world/gregs/voidps/engine/queue/ActionPriority.kt +++ b/engine/src/main/kotlin/world/gregs/voidps/engine/queue/ActionPriority.kt @@ -19,7 +19,7 @@ enum class ActionPriority( Strong(closeInterfaces = true), /** - * Closes interfaces and can't be paused or canceled be anything other than suspensions + * Closes interfaces and can't be paused or canceled by anything other than suspensions */ Soft(closeInterfaces = true) } \ No newline at end of file diff --git a/engine/src/main/kotlin/world/gregs/voidps/engine/suspend/DialogueSuspension.kt b/engine/src/main/kotlin/world/gregs/voidps/engine/suspend/DialogueSuspension.kt index b5ee999871..6e2b17c726 100644 --- a/engine/src/main/kotlin/world/gregs/voidps/engine/suspend/DialogueSuspension.kt +++ b/engine/src/main/kotlin/world/gregs/voidps/engine/suspend/DialogueSuspension.kt @@ -22,8 +22,20 @@ sealed class DialogueSuspension { } } -data object ContinueSuspension : DialogueSuspension() +class ContinueSuspension : DialogueSuspension() { + companion object { + suspend fun get(player: Player) = ContinueSuspension().get(player) + } +} -data object StringSuspension : DialogueSuspension() +class StringSuspension : DialogueSuspension() { + companion object { + suspend fun get(player: Player) = StringSuspension().get(player) + } +} -data object IntSuspension : DialogueSuspension() +class IntSuspension : DialogueSuspension() { + companion object { + suspend fun get(player: Player) = IntSuspension().get(player) + } +} diff --git a/engine/src/main/kotlin/world/gregs/voidps/engine/suspend/SuspendableContext.kt b/engine/src/main/kotlin/world/gregs/voidps/engine/suspend/SuspendableContext.kt index cdb999de46..b3800c5a4b 100644 --- a/engine/src/main/kotlin/world/gregs/voidps/engine/suspend/SuspendableContext.kt +++ b/engine/src/main/kotlin/world/gregs/voidps/engine/suspend/SuspendableContext.kt @@ -1,5 +1,6 @@ package world.gregs.voidps.engine.suspend +import com.github.michaelbull.logging.InlineLogger import kotlinx.coroutines.suspendCancellableCoroutine import world.gregs.voidps.engine.entity.character.Character import world.gregs.voidps.engine.event.Context @@ -33,7 +34,7 @@ interface SuspendableContext : Context { * Delay until the appeared location of the character has moved [delta] in [delay] time */ suspend fun Character.exactMoveDelay(delta: Delta, delay: Int = tile.distanceTo(tile.add(delta)) * 30, direction: Direction = Direction.NONE) { - character.exactMove(delta, delay, direction) + exactMove(delta, delay, direction) delay(delay / 30) } @@ -41,7 +42,7 @@ interface SuspendableContext : Context { * Delay until the appeared location of the character has moved to [target] in [delay] time */ suspend fun Character.exactMoveDelay(target: Tile, delay: Int = tile.distanceTo(target) * 30, direction: Direction = Direction.NONE, startDelay: Int = 0) { - character.exactMove(target, delay, direction, startDelay) + exactMove(target, delay, direction, startDelay) delay((startDelay + delay) / 30) } @@ -70,9 +71,17 @@ interface SuspendableContext : Context { delayTarget(tile) } - private suspend fun delayTarget(target: Tile) { - while (character.tile != target) { + private suspend fun Character.delayTarget(target: Tile) { + var count = 0 + while (tile != target && count++ < 50) { delay() } + if (count >= 50) { + logger.warn { "Failed delaying target char=$this, target=$target, context=${this@SuspendableContext}" } + } + } + + companion object { + private val logger = InlineLogger() } } \ No newline at end of file diff --git a/engine/src/test/kotlin/world/gregs/voidps/engine/data/AccountStorageTest.kt b/engine/src/test/kotlin/world/gregs/voidps/engine/data/AccountStorageTest.kt index 83d3b843cd..6927b63b7e 100644 --- a/engine/src/test/kotlin/world/gregs/voidps/engine/data/AccountStorageTest.kt +++ b/engine/src/test/kotlin/world/gregs/voidps/engine/data/AccountStorageTest.kt @@ -239,16 +239,16 @@ abstract class AccountStorageTest { ), inventories = mapOf( "worn_equipment" to Array(14) { Item.EMPTY }.apply { - this[0] = Item("green_partyhat", 1) - this[1] = Item("fire_cape", 1) - this[2] = Item("amulet_of_fury", 1) - this[3] = Item("abyssal_whip", 1) - this[4] = Item("ahrims_robe_top", 1) - this[5] = Item("toktz_ket_xil", 1) - this[7] = Item("ahrims_robe_skirt", 1) - this[9] = Item("culinaromancers_gloves_10", 1) - this[10] = Item("rock_climbing_boots", 1) - this[12] = Item("berserker_ring", 1) + this[0] = Item("green_partyhat") + this[1] = Item("fire_cape") + this[2] = Item("amulet_of_fury") + this[3] = Item("abyssal_whip") + this[4] = Item("ahrims_robe_top") + this[5] = Item("toktz_ket_xil") + this[7] = Item("ahrims_robe_skirt") + this[9] = Item("culinaromancers_gloves_10") + this[10] = Item("rock_climbing_boots") + this[12] = Item("berserker_ring") }, "inventory" to Array(28) { Item.EMPTY }.apply { this[0] = Item("armadyl_godsword") diff --git a/engine/src/test/resources/player.json b/engine/src/test/resources/player.json index 98581b45ef..1bd1e52df5 100644 --- a/engine/src/test/resources/player.json +++ b/engine/src/test/resources/player.json @@ -34,7 +34,7 @@ }, "inventories": { "worn_equipment": [ { "id": "green_partyhat", "amount": 1 }, { "id": "fire_cape", "amount": 1 }, { "id": "amulet_of_fury", "amount": 1 }, { "id": "abyssal_whip", "amount": 1 }, { "id": "ahrims_robe_top", "amount": 1 }, { "id": "toktz_ket_xil", "amount": 1 }, {}, { "id": "ahrims_robe_skirt", "amount": 1 }, {}, { "id": "culinaromancers_gloves_10", "amount": 1 }, { "id": "rock_climbing_boots", "amount": 1 }, {}, { "id": "berserker_ring", "amount": 1 }, {} ], - "inventory": [ { "id": "armadyl_godsword", "amount": 0 }, { "id": "prayer_potion_4", "amount": 0 }, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {} ], + "inventory": [ { "id": "armadyl_godsword", "amount": 1 }, { "id": "prayer_potion_4", "amount": 1 }, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {} ], "bank": [ { "id": "coins", "amount": 420000000 }, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {} ] }, "friends": { diff --git a/game/src/main/kotlin/content/achievement/TaskSystem.kts b/game/src/main/kotlin/content/achievement/TaskSystem.kts index fc4cc63a2a..744bcb9274 100644 --- a/game/src/main/kotlin/content/achievement/TaskSystem.kts +++ b/game/src/main/kotlin/content/achievement/TaskSystem.kts @@ -15,6 +15,7 @@ import world.gregs.voidps.engine.entity.character.mode.move.exitArea import world.gregs.voidps.engine.entity.character.player.Player import world.gregs.voidps.engine.inject import content.entity.player.modal.Tab +import content.entity.player.modal.tab val variables: VariableDefinitions by inject() val enumDefinitions: EnumDefinitions by inject() @@ -161,7 +162,7 @@ fun areaId(player: Player) = variables.get("task_area")!!.values.toInt(player["t interfaceOption("Details", "details", "task_popup") { player["task_popup_summary"] = true - player["tab"] = Tab.TaskSystem.name + player.tab(Tab.TaskSystem) } variableSet("*_task") { player -> diff --git a/game/src/main/kotlin/content/achievement/Tasks.kt b/game/src/main/kotlin/content/achievement/Tasks.kt index 11253f1c06..57b6a78823 100644 --- a/game/src/main/kotlin/content/achievement/Tasks.kt +++ b/game/src/main/kotlin/content/achievement/Tasks.kt @@ -14,7 +14,7 @@ import world.gregs.voidps.engine.entity.character.player.skill.level.Level.has import world.gregs.voidps.engine.entity.character.player.skill.level.Level.hasMax import world.gregs.voidps.engine.entity.character.player.summoningCombatLevel import world.gregs.voidps.engine.get -import content.quest.questComplete +import content.quest.questCompleted import java.util.* import java.util.Calendar.HOUR_OF_DAY import java.util.concurrent.TimeUnit @@ -67,7 +67,7 @@ object Tasks { 63 -> return hasRequirements(player, definition.id) 62 -> { val quest = get().get(value) - if (player.questComplete(quest.stringId)) { + if (player.questCompleted(quest.stringId)) { return false } } @@ -118,9 +118,9 @@ object Tasks { 12 -> player["penguin_hide_and_seek_explained", false] 23 -> player["fairy_rings_unlocked", false] 49 -> player["unlocked_emote_air_guitar", false] - 59 -> player.questComplete("into_the_abyss") + 59 -> player.questCompleted("into_the_abyss") 147, 167 -> player["fairy_rings_unlocked", false] - 107 -> player.getInt("dragon_slayer", "unstarted") >= 2 && player["dragon_slayer_received_shield", false] || player.questComplete("dragon_slayer") + 107 -> player.getInt("dragon_slayer", "unstarted") >= 2 && player["dragon_slayer_received_shield", false] || player.questCompleted("dragon_slayer") 219 -> player.combatLevel >= 100 331 -> player.summoningCombatLevel >= 100 276, 3011 -> player["quest_points", 0] >= 33 diff --git a/game/src/main/kotlin/content/area/asgarnia/falador/Doric.kts b/game/src/main/kotlin/content/area/asgarnia/falador/Doric.kts index b415694ec8..e0bd677621 100644 --- a/game/src/main/kotlin/content/area/asgarnia/falador/Doric.kts +++ b/game/src/main/kotlin/content/area/asgarnia/falador/Doric.kts @@ -15,7 +15,7 @@ import world.gregs.voidps.engine.queue.softQueue import world.gregs.voidps.engine.suspend.SuspendableContext import content.quest.quest import content.quest.refreshQuestJournal -import content.quest.sendQuestComplete +import content.quest.questComplete import content.entity.player.dialogue.* import content.entity.player.dialogue.type.* import content.entity.sound.playJingle @@ -149,11 +149,13 @@ fun Context.questComplete() { player.refreshQuestJournal() player.inc("quest_points") player.softQueue("quest_complete", 1) { - player.sendQuestComplete("Doric's Quest", listOf( + player.questComplete( + "Doric's Quest", "1 Quest Point", "1300 Mining XP", "180 coins", - "Use of Doric's Anvils" - ), Item("steel_pickaxe")) + "Use of Doric's Anvils", + item = "steel_pickaxe" + ) } } diff --git a/game/src/main/kotlin/content/area/asgarnia/falador/GiantMole.kts b/game/src/main/kotlin/content/area/asgarnia/falador/GiantMole.kts index a027725352..25c8cf1f93 100644 --- a/game/src/main/kotlin/content/area/asgarnia/falador/GiantMole.kts +++ b/game/src/main/kotlin/content/area/asgarnia/falador/GiantMole.kts @@ -1,6 +1,13 @@ package content.area.asgarnia.falador import com.github.michaelbull.logging.InlineLogger +import content.entity.combat.attackers +import content.entity.combat.hit.npcCombatDamage +import content.entity.gfx.areaGraphic +import content.entity.player.inv.inventoryItem +import content.entity.sound.areaSound +import content.skill.firemaking.Light.hasLightSource +import content.skill.melee.weapon.fightStyle import world.gregs.voidps.engine.client.ui.close import world.gregs.voidps.engine.client.ui.closeInterfaces import world.gregs.voidps.engine.client.ui.interfaceOption @@ -20,7 +27,6 @@ import world.gregs.voidps.engine.entity.character.player.skill.Skill import world.gregs.voidps.engine.entity.obj.objectOperate import world.gregs.voidps.engine.entity.playerSpawn import world.gregs.voidps.engine.inject -import world.gregs.voidps.engine.inv.equipment import world.gregs.voidps.engine.inv.inventory import world.gregs.voidps.engine.inv.itemChange import world.gregs.voidps.engine.inv.transact.operation.ReplaceItem.replace @@ -28,12 +34,6 @@ import world.gregs.voidps.engine.map.collision.random import world.gregs.voidps.engine.queue.queue import world.gregs.voidps.type.Direction import world.gregs.voidps.type.Tile -import content.entity.combat.attackers -import content.skill.melee.weapon.fightStyle -import content.entity.combat.hit.npcCombatHit -import content.entity.gfx.areaGraphic -import content.entity.player.inv.inventoryItem -import content.entity.sound.areaSound import kotlin.random.Random val logger = InlineLogger() @@ -73,7 +73,7 @@ interfaceOption(component = "stayout", id = "warning_dark") { player.closeInterfaces() } -npcCombatHit("giant_mole") { +npcCombatDamage("giant_mole") { val currentHealth = it.levels.get(Skill.Constitution) var shouldBurrow = false if (it.fightStyle == "magic" && damage != 0) { @@ -193,23 +193,4 @@ itemChange("inventory") { player: Player -> player.close("level_three_darkness") } } -} - -fun hasLightSource(player: Player): Boolean { - val playerItems = player.inventory.items - val playerEquipment = player.equipment.items - - for (item in playerItems) { - if (item.id.endsWith("lantern_lit") || item.id.endsWith("candle_lit") || item.id == "firemaking_cape_t" || item.id == "firemaking_cape") { - return true - } - } - - for (equipmentItem in playerEquipment) { - if (equipmentItem.id == "firemaking_cape" || equipmentItem.id == "firemaking_cape_t") { - return true - } - } - - return false -} +} \ No newline at end of file diff --git a/game/src/main/kotlin/content/area/asgarnia/falador/MakeoverMage.kts b/game/src/main/kotlin/content/area/asgarnia/falador/MakeoverMage.kts index 3ccb42448f..a83a0fa4e8 100644 --- a/game/src/main/kotlin/content/area/asgarnia/falador/MakeoverMage.kts +++ b/game/src/main/kotlin/content/area/asgarnia/falador/MakeoverMage.kts @@ -216,7 +216,7 @@ npcTimerTick("makeover") { npc -> val current: String = npc["transform_id", "makeover_mage_male"] val toFemale = current == "makeover_mage_male" npc.transform = if (toFemale) "makeover_mage_female" else "makeover_mage_male" - npc.gfx("curse_hit", delay = 15) + npc.gfx("curse_impact", delay = 15) npc.anim("bind_staff") npc.softQueue("transform", 1) { npc.say(if (toFemale) "Ooh!" else "Aha!") diff --git a/game/src/main/kotlin/content/area/asgarnia/falador/SquireAsrol.kts b/game/src/main/kotlin/content/area/asgarnia/falador/SquireAsrol.kts index df2f3d246f..f68dcc853e 100644 --- a/game/src/main/kotlin/content/area/asgarnia/falador/SquireAsrol.kts +++ b/game/src/main/kotlin/content/area/asgarnia/falador/SquireAsrol.kts @@ -1,25 +1,24 @@ package content.area.asgarnia.falador +import content.entity.player.bank.ownsItem +import content.entity.player.dialogue.* +import content.entity.player.dialogue.type.* +import content.entity.sound.playJingle +import content.quest.quest +import content.quest.refreshQuestJournal +import content.quest.questComplete import world.gregs.voidps.engine.client.message -import world.gregs.voidps.engine.event.Context import world.gregs.voidps.engine.entity.character.npc.npcOperate import world.gregs.voidps.engine.entity.character.player.Player import world.gregs.voidps.engine.entity.character.player.combatLevel import world.gregs.voidps.engine.entity.character.player.skill.Skill -import world.gregs.voidps.engine.entity.item.Item +import world.gregs.voidps.engine.event.Context import world.gregs.voidps.engine.inv.equipment import world.gregs.voidps.engine.inv.holdsItem import world.gregs.voidps.engine.inv.inventory import world.gregs.voidps.engine.inv.remove import world.gregs.voidps.engine.queue.softQueue import world.gregs.voidps.engine.suspend.SuspendableContext -import content.entity.player.bank.ownsItem -import content.quest.quest -import content.quest.refreshQuestJournal -import content.quest.sendQuestComplete -import content.entity.player.dialogue.* -import content.entity.player.dialogue.type.* -import content.entity.sound.playJingle npcOperate("Talk-to", "squire_asrol") { when (player.quest("the_knights_sword")) { @@ -197,9 +196,11 @@ fun Context.questComplete() { player.inc("quest_points") player.message("Congratulations! Quest complete!") player.softQueue("quest_complete", 1) { - player.sendQuestComplete("The Knight's Sword Quest", listOf( + player.questComplete( + "The Knight's Sword Quest", "1 Quest Point", - "12,725 Smithing XP" - ), Item("blurite_sword")) + "12,725 Smithing XP", + item = "blurite_sword" + ) } } diff --git a/game/src/main/kotlin/content/area/asgarnia/port_sarim/PortSarim.kts b/game/src/main/kotlin/content/area/asgarnia/port_sarim/PortSarim.kts index 9db70f3b61..41d398ed8b 100644 --- a/game/src/main/kotlin/content/area/asgarnia/port_sarim/PortSarim.kts +++ b/game/src/main/kotlin/content/area/asgarnia/port_sarim/PortSarim.kts @@ -1,30 +1,19 @@ package content.area.asgarnia.port_sarim +import content.entity.player.inv.item.take.canTake +import content.entity.player.inv.item.take.taken import world.gregs.voidps.engine.client.message -import world.gregs.voidps.engine.entity.character.player.chat.inventoryFull -import world.gregs.voidps.engine.entity.item.floor.FloorItems -import world.gregs.voidps.engine.entity.item.floor.floorItemOperate -import world.gregs.voidps.engine.inject -import world.gregs.voidps.engine.inv.add import world.gregs.voidps.engine.inv.holdsItem -import world.gregs.voidps.engine.inv.inventory -import content.entity.sound.playSound -val items: FloorItems by inject() - -floorItemOperate("Take", "white_apron_port_sarim", override = false) { +canTake("white_apron_port_sarim") { player -> if (player.holdsItem("white_apron")) { player.message("You already have one of those.") cancel() - } else if (player.inventory.isFull() && (!player.inventory.stackable(target.id) || !player.inventory.contains(target.id))) { - player.inventoryFull() - cancel() - } else { - player.anim("take") - player.playSound("pickup_item") - items.remove(target) - player.inventory.add("white_apron") - player.message("You take an apron. It feels freshly starched and smells of laundry.") - cancel() } + item = "white_apron" +} + +taken("white_apron_port_sarim") { player -> + player.anim("take") + player.message("You take an apron. It feels freshly starched and smells of laundry.") } \ No newline at end of file diff --git a/game/src/main/kotlin/content/area/asgarnia/port_sarim/Thurgo.kts b/game/src/main/kotlin/content/area/asgarnia/port_sarim/Thurgo.kts index 5f0ce3db7c..d39d6be8fd 100644 --- a/game/src/main/kotlin/content/area/asgarnia/port_sarim/Thurgo.kts +++ b/game/src/main/kotlin/content/area/asgarnia/port_sarim/Thurgo.kts @@ -43,7 +43,7 @@ suspend fun PlayerChoice.madeSword() = option( } val items = listOf( - Item("blurite_ore", 1), + Item("blurite_ore"), Item("iron_bar", 2) ) diff --git a/game/src/main/kotlin/content/area/asgarnia/taverley/Kaqemeex.kts b/game/src/main/kotlin/content/area/asgarnia/taverley/Kaqemeex.kts index 94dc40783c..75aebc79ad 100644 --- a/game/src/main/kotlin/content/area/asgarnia/taverley/Kaqemeex.kts +++ b/game/src/main/kotlin/content/area/asgarnia/taverley/Kaqemeex.kts @@ -6,7 +6,6 @@ import world.gregs.voidps.engine.entity.character.player.Player import world.gregs.voidps.engine.entity.character.player.name import world.gregs.voidps.engine.entity.character.player.skill.Skill import world.gregs.voidps.engine.entity.character.player.skill.level.Level.hasMax -import world.gregs.voidps.engine.entity.item.Item import world.gregs.voidps.engine.inv.inventory import world.gregs.voidps.engine.inv.transact.TransactionError import world.gregs.voidps.engine.inv.transact.operation.AddItem.add @@ -15,7 +14,7 @@ import world.gregs.voidps.engine.queue.softQueue import world.gregs.voidps.engine.suspend.SuspendableContext import content.quest.quest import content.quest.refreshQuestJournal -import content.quest.sendQuestComplete +import content.quest.questComplete import content.entity.player.dialogue.type.npc import content.entity.player.dialogue.* import content.entity.player.dialogue.type.choice @@ -178,12 +177,12 @@ fun Context.questComplete() { player.refreshQuestJournal() player.inc("quest_points", 4) player.softQueue("quest_complete", 1) { - player.sendQuestComplete( - "Druidic Ritual", listOf( - "4 Quest Points", - "Access to the Herblore Skill", - "250 Herblore XP", - ), Item("clean_marrentill") + player.questComplete( + "Druidic Ritual", + "4 Quest Points", + "Access to the Herblore Skill", + "250 Herblore XP", + item = "clean_marrentill" ) } } diff --git a/game/src/main/kotlin/content/area/asgarnia/taverley/Sanfew.kts b/game/src/main/kotlin/content/area/asgarnia/taverley/Sanfew.kts index 31bab8d8d6..1fd8b37adb 100644 --- a/game/src/main/kotlin/content/area/asgarnia/taverley/Sanfew.kts +++ b/game/src/main/kotlin/content/area/asgarnia/taverley/Sanfew.kts @@ -15,10 +15,10 @@ import content.entity.player.dialogue.type.player import content.entity.player.dialogue.type.statement val enchantedMeat = listOf( - Item("enchanted_beef", 1), - Item("enchanted_rat_meat", 1), - Item("enchanted_bear_meat", 1), - Item("enchanted_chicken", 1) + Item("enchanted_beef"), + Item("enchanted_rat_meat"), + Item("enchanted_bear_meat"), + Item("enchanted_chicken") ) npcOperate("Talk-to", "sanfew") { diff --git a/game/src/main/kotlin/content/area/kandarin/ardougne/WizardCromperty.kts b/game/src/main/kotlin/content/area/kandarin/ardougne/WizardCromperty.kts index 987538b924..5fd56c9baf 100644 --- a/game/src/main/kotlin/content/area/kandarin/ardougne/WizardCromperty.kts +++ b/game/src/main/kotlin/content/area/kandarin/ardougne/WizardCromperty.kts @@ -6,7 +6,7 @@ import world.gregs.voidps.engine.entity.character.npc.NPCOption import world.gregs.voidps.engine.entity.character.npc.npcOperate import world.gregs.voidps.engine.entity.character.player.Player import world.gregs.voidps.engine.queue.softQueue -import content.quest.questComplete +import content.quest.questCompleted import content.skill.runecrafting.EssenceMine import content.entity.player.dialogue.* import content.entity.player.dialogue.type.ChoiceBuilder @@ -30,14 +30,14 @@ npcOperate("Talk-to", "wizard_cromperty") { } } whatHaveYouInvented() - option("Can you teleport me to the Rune Essence Mine?", filter = { player.questComplete("rune_mysteries") }) { + option("Can you teleport me to the Rune Essence Mine?", filter = { player.questCompleted("rune_mysteries") }) { EssenceMine.teleport(target, player) } } } npcOperate("Teleport", "wizard_cromperty") { - if (player.questComplete("rune_mysteries")) { + if (player.questCompleted("rune_mysteries")) { EssenceMine.teleport(target, player) } else { player.message("You need to have completed the Rune Mysteries Quest to use this feature.") @@ -73,7 +73,7 @@ fun ChoiceBuilder>.teleportMe() { choice { option("Yes, that sounds good. Teleport me!") { npc("Okey dokey! Ready?") - player.gfx("curse_hit") + player.gfx("curse_impact") target.gfx("curse_cast") target.say("Dipsolum sententa sententi!") target.shoot("curse", player.tile, offset = 64) diff --git a/game/src/main/kotlin/content/area/kandarin/barbarian_outpost/BarbarianOutpostGate.kts b/game/src/main/kotlin/content/area/kandarin/barbarian_outpost/BarbarianOutpostGate.kts index 6c93441b7d..b069ffcf6d 100644 --- a/game/src/main/kotlin/content/area/kandarin/barbarian_outpost/BarbarianOutpostGate.kts +++ b/game/src/main/kotlin/content/area/kandarin/barbarian_outpost/BarbarianOutpostGate.kts @@ -6,13 +6,13 @@ import world.gregs.voidps.engine.entity.character.npc.NPCOption import world.gregs.voidps.engine.entity.character.npc.NPCs import world.gregs.voidps.engine.entity.obj.objectOperate import world.gregs.voidps.engine.inject -import content.quest.questComplete +import content.quest.questCompleted import content.entity.obj.door.enterDoor val npcs: NPCs by inject() objectOperate("Open", "barbarian_outpost_gate_left_closed", "barbarian_outpost_gate_right_closed") { - if (!player.questComplete("alfred_grimhands_barcrawl")) { + if (!player.questCompleted("alfred_grimhands_barcrawl")) { val guard = npcs[player.tile.regionLevel].firstOrNull { it.id == "barbarian_guard" } ?: return@objectOperate player.talkWith(guard) player.mode = Interact(player, guard, NPCOption(player, guard, guard.def, "Talk-to")) diff --git a/game/src/main/kotlin/content/area/kandarin/tree_gnome_stronghold/Brimstail.kts b/game/src/main/kotlin/content/area/kandarin/tree_gnome_stronghold/Brimstail.kts index 5fcafa741c..6854cd409a 100644 --- a/game/src/main/kotlin/content/area/kandarin/tree_gnome_stronghold/Brimstail.kts +++ b/game/src/main/kotlin/content/area/kandarin/tree_gnome_stronghold/Brimstail.kts @@ -2,7 +2,7 @@ package content.area.kandarin.tree_gnome_stronghold import world.gregs.voidps.engine.client.message import world.gregs.voidps.engine.entity.character.npc.npcOperate -import content.quest.questComplete +import content.quest.questCompleted import content.skill.runecrafting.EssenceMine import content.entity.player.dialogue.Happy import content.entity.player.dialogue.Quiz @@ -13,7 +13,7 @@ import content.entity.player.dialogue.type.player import content.entity.obj.teleportTakeOff npcOperate("Talk-to", "brimstail") { - if (!player.questComplete("rune_mysteries")) { + if (!player.questCompleted("rune_mysteries")) { npc("Hello adventurer, what can I do for you?") player("What's that cute creature wandering around?") npc("Oh Izzie? He's my pet.") @@ -37,7 +37,7 @@ npcOperate("Talk-to", "brimstail") { } npcOperate("Teleport", "brimstail") { - if (player.questComplete("rune_mysteries")) { + if (player.questCompleted("rune_mysteries")) { EssenceMine.teleport(target, player) } else { player.message("You need to have completed the Rune Mysteries Quest to use this feature.") diff --git a/game/src/main/kotlin/content/area/kandarin/yanille/WizardDistentor.kts b/game/src/main/kotlin/content/area/kandarin/yanille/WizardDistentor.kts index a75341566a..57666b054b 100644 --- a/game/src/main/kotlin/content/area/kandarin/yanille/WizardDistentor.kts +++ b/game/src/main/kotlin/content/area/kandarin/yanille/WizardDistentor.kts @@ -2,7 +2,7 @@ package content.area.kandarin.yanille import world.gregs.voidps.engine.client.message import world.gregs.voidps.engine.entity.character.npc.npcOperate -import content.quest.questComplete +import content.quest.questCompleted import content.skill.runecrafting.EssenceMine import content.entity.player.dialogue.Quiz import content.entity.player.dialogue.Talk @@ -12,7 +12,7 @@ import content.entity.player.dialogue.type.player npcOperate("Talk-to", "wizard_distentor") { npc("Welcome to the Magicians' Guild!") - if (!player.questComplete("rune_mysteries")) { + if (!player.questCompleted("rune_mysteries")) { return@npcOperate } player("Hello there.") @@ -28,7 +28,7 @@ npcOperate("Talk-to", "wizard_distentor") { } npcOperate("Teleport", "wizard_distentor") { - if (player.questComplete("rune_mysteries")) { + if (player.questCompleted("rune_mysteries")) { EssenceMine.teleport(target, player) } else { player.message("You need to have completed the Rune Mysteries Quest to use this feature.") diff --git a/game/src/main/kotlin/content/area/misthalin/barbarian_village/Dororan.kts b/game/src/main/kotlin/content/area/misthalin/barbarian_village/Dororan.kts index 2c82cadad5..49f6853297 100644 --- a/game/src/main/kotlin/content/area/misthalin/barbarian_village/Dororan.kts +++ b/game/src/main/kotlin/content/area/misthalin/barbarian_village/Dororan.kts @@ -14,7 +14,7 @@ import world.gregs.voidps.engine.queue.softQueue import world.gregs.voidps.engine.suspend.SuspendableContext import content.entity.player.bank.ownsItem import content.quest.quest -import content.quest.questComplete +import content.quest.questCompleted import content.quest.refreshQuestJournal import content.entity.player.dialogue.* import content.entity.player.dialogue.type.* @@ -1060,7 +1060,7 @@ suspend fun SuspendableContext.helpMe() { } npcOperate("Talk-to", "dororan_after_quest") { - if (!player.questComplete("gunnars_ground")) { + if (!player.questCompleted("gunnars_ground")) { return@npcOperate } if (player["dororan_ruby_bracelet", 0] != 1) { diff --git a/game/src/main/kotlin/content/area/misthalin/barbarian_village/Gudrun.kts b/game/src/main/kotlin/content/area/misthalin/barbarian_village/Gudrun.kts index ebb3710416..e1eb97dc8b 100644 --- a/game/src/main/kotlin/content/area/misthalin/barbarian_village/Gudrun.kts +++ b/game/src/main/kotlin/content/area/misthalin/barbarian_village/Gudrun.kts @@ -13,7 +13,6 @@ import world.gregs.voidps.engine.entity.character.npc.NPCs import world.gregs.voidps.engine.entity.character.npc.npcOperate import world.gregs.voidps.engine.entity.character.player.Player import world.gregs.voidps.engine.entity.character.player.skill.Skill -import world.gregs.voidps.engine.entity.item.Item import world.gregs.voidps.engine.entity.obj.GameObjects import world.gregs.voidps.engine.entity.obj.ObjectShape import world.gregs.voidps.engine.inject @@ -29,7 +28,7 @@ import world.gregs.voidps.type.Direction import world.gregs.voidps.type.Region import world.gregs.voidps.type.Tile import content.quest.quest -import content.quest.sendQuestComplete +import content.quest.questComplete import content.quest.startCutscene import content.quest.stopCutscene import content.entity.player.dialogue.* @@ -199,7 +198,7 @@ suspend fun SuspendableContext.cutscenePart2(instance: Region) { } player.moveCamera(Tile(3084, 3421).add(offset), 350) player.turnCamera(Tile(3082, 3426).add(offset), 250) - val gudrunHugging = objects.add("gudrun_and_dororan", Tile(3082,3426).add(offset), shape = ObjectShape.CENTRE_PIECE_STRAIGHT, rotation = 1) + val gudrunHugging = objects.add("gudrun_and_dororan", Tile(3082, 3426).add(offset), shape = ObjectShape.CENTRE_PIECE_STRAIGHT, rotation = 1) player.open("fade_in") npc("gudrun_cutscene", "That was brilliant! I must know who wrote that poem.") npc("dororan_cutscene", "Um, that would be me. Hello") @@ -497,12 +496,14 @@ fun Context.questComplete() { player.inc("quest_points", 5) player.experience.add(Skill.Crafting, 300.0) player.softQueue("quest_complete", 1) { - player.sendQuestComplete("Gunnar's Ground", listOf( + player.questComplete( + "Gunnar's Ground", "5 Quest Points", "300 Crafting XP.", "Antique lamp.", - "Swanky boots." - ), Item("gunnars_ground")) + "Swanky boots.", + item = "gunnars_ground" + ) } player.inventory.add("antique_lamp_gunnars_ground") player.inventory.add("swanky_boots") diff --git a/game/src/main/kotlin/content/area/misthalin/lumbridge/Cook.kts b/game/src/main/kotlin/content/area/misthalin/lumbridge/Cook.kts index d1a82ff891..9c11a5b344 100644 --- a/game/src/main/kotlin/content/area/misthalin/lumbridge/Cook.kts +++ b/game/src/main/kotlin/content/area/misthalin/lumbridge/Cook.kts @@ -6,7 +6,6 @@ import world.gregs.voidps.engine.entity.character.npc.NPCOption import world.gregs.voidps.engine.entity.character.npc.npcOperate import world.gregs.voidps.engine.entity.character.player.Player import world.gregs.voidps.engine.entity.character.player.skill.Skill -import world.gregs.voidps.engine.entity.item.Item import world.gregs.voidps.engine.inv.add import world.gregs.voidps.engine.inv.holdsItem import world.gregs.voidps.engine.inv.inventory @@ -14,7 +13,7 @@ import world.gregs.voidps.engine.inv.remove import world.gregs.voidps.engine.suspend.SuspendableContext import content.quest.quest import content.quest.refreshQuestJournal -import content.quest.sendQuestComplete +import content.quest.questComplete import content.entity.player.dialogue.* import content.entity.player.dialogue.type.* import content.entity.sound.playJingle @@ -122,14 +121,15 @@ fun Context.questComplete() { player.inc("quest_points") player.message("Congratulations, you've completed a quest: cook's assistant") player.refreshQuestJournal() - val lines = listOf( + player.questComplete( + "cook's assistant", "1 Quest Point", "300 Cooking XP", "500 coins", "20 sardines", - "Access to the cook's range" + "Access to the cook's range", + item = "cake" ) - player.sendQuestComplete("cook's assistant", lines, Item("cake")) } suspend fun SuspendableContext.startQuest() { diff --git a/game/src/main/kotlin/content/area/misthalin/lumbridge/LumbridgeChurch.kts b/game/src/main/kotlin/content/area/misthalin/lumbridge/LumbridgeChurch.kts index 0ff548445f..afd85698b7 100644 --- a/game/src/main/kotlin/content/area/misthalin/lumbridge/LumbridgeChurch.kts +++ b/game/src/main/kotlin/content/area/misthalin/lumbridge/LumbridgeChurch.kts @@ -11,7 +11,6 @@ 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.skill.Skill -import world.gregs.voidps.engine.entity.item.Item import world.gregs.voidps.engine.entity.obj.objectOperate import world.gregs.voidps.engine.entity.obj.replace import world.gregs.voidps.engine.entity.playerSpawn @@ -121,12 +120,12 @@ fun Context.questComplete() { player.refreshQuestJournal() player.inc("quest_points") player.softQueue("quest_complete", 1) { - player.sendQuestComplete( - "The Restless Ghost", listOf( - "1 Quest Point", - "1,125 Prayer XP", - "A Ghostspeak Amulet", - ), Item("muddy_skull") + player.questComplete( + "The Restless Ghost", + "1 Quest Point", + "1,125 Prayer XP", + "A Ghostspeak Amulet", + item = "muddy_skull" ) } } @@ -140,7 +139,7 @@ objectOperate("Open", "restless_ghost_coffin_closed") { player.animDelay("open_chest") player.playSound("coffin_open") target.replace("coffin_restless_ghost_2", ticks = TimeUnit.MINUTES.toTicks(3)) - if (!player.questComplete("the_restless_ghost")) { + if (!player.questCompleted("the_restless_ghost")) { spawnGhost() } } @@ -150,7 +149,7 @@ objectOperate("Search", "restless_ghost_coffin_closed") { player.animDelay("open_chest") player.playSound("coffin_open") target.replace("coffin_restless_ghost_2", ticks = TimeUnit.MINUTES.toTicks(3)) - if (!player.questComplete("the_restless_ghost")) { + if (!player.questCompleted("the_restless_ghost")) { spawnGhost() } } diff --git a/game/src/main/kotlin/content/area/misthalin/lumbridge/chicken_farm/SethGroatsFarm.kts b/game/src/main/kotlin/content/area/misthalin/lumbridge/chicken_farm/SethGroatsFarm.kts index 9f67dda8d6..76df289f61 100644 --- a/game/src/main/kotlin/content/area/misthalin/lumbridge/chicken_farm/SethGroatsFarm.kts +++ b/game/src/main/kotlin/content/area/misthalin/lumbridge/chicken_farm/SethGroatsFarm.kts @@ -1,16 +1,15 @@ package content.area.misthalin.lumbridge.chicken_farm +import content.entity.player.bank.ownsItem +import content.entity.player.inv.item.take.canTake +import content.quest.questCompleted import world.gregs.voidps.engine.client.message import world.gregs.voidps.engine.entity.character.player.chat.inventoryFull -import world.gregs.voidps.engine.entity.item.floor.floorItemOperate import world.gregs.voidps.engine.entity.obj.objectOperate import world.gregs.voidps.engine.entity.obj.replace import world.gregs.voidps.engine.inv.add -import world.gregs.voidps.engine.inv.holdsItem import world.gregs.voidps.engine.inv.inventory import world.gregs.voidps.engine.timer.toTicks -import content.entity.player.bank.bank -import content.quest.questComplete import java.util.concurrent.TimeUnit objectOperate("Take-hatchet", "hatchet_logs") { @@ -21,11 +20,11 @@ objectOperate("Take-hatchet", "hatchet_logs") { } } -floorItemOperate("Take", "super_large_egg", override = false) { - if (player.questComplete("cooks_assistant")) { +canTake("super_large_egg") { player -> + if (player.questCompleted("cooks_assistant")) { player.message("You've no reason to pick that up; eggs of that size are only useful for royal cakes.") cancel() - } else if (player.holdsItem("super_large_egg") || player.bank.contains("super_large_egg")) { + } else if (player.ownsItem("super_large_egg")) { player.message("You've already got one of those eggs and one's enough.") cancel() } diff --git a/game/src/main/kotlin/content/area/misthalin/lumbridge/combat_hall/MagicTutor.kts b/game/src/main/kotlin/content/area/misthalin/lumbridge/combat_hall/MagicTutor.kts index d8ea116537..b40bb0979e 100644 --- a/game/src/main/kotlin/content/area/misthalin/lumbridge/combat_hall/MagicTutor.kts +++ b/game/src/main/kotlin/content/area/misthalin/lumbridge/combat_hall/MagicTutor.kts @@ -19,6 +19,7 @@ import content.entity.player.dialogue.type.choice import content.entity.player.dialogue.type.item import content.entity.player.dialogue.type.npc import content.entity.player.modal.Tab +import content.entity.player.modal.tab import java.util.concurrent.TimeUnit npcOperate("Talk-to", "mikasi") { @@ -52,7 +53,7 @@ suspend fun PlayerChoice.runeMaking(): Unit = option("How do I make runes? if (player.experience.get(Skill.Runecrafting) > 0.0) { npc("To get rune essence you will need to gather them in the essence mine. You can get to the mine by talking to Aubury who owns the runes shop in south east Varrock.") npc("I see you have some experience already in Runecrafting. Perhaps you should try crafting some runes which you can then use in magic.") - player["tab"] = Tab.Stats.name + player.tab(Tab.Stats) npc("Check the skill guide to see which runes you can craft.") } else { npc("To get rune essence you will need to gather them somehow. You should talk to the Duke of Lumbridge, he may be able to help you with that. Alternatively, other players may sell you the essence.") diff --git a/game/src/main/kotlin/content/area/misthalin/lumbridge/combat_hall/MeleeTutor.kts b/game/src/main/kotlin/content/area/misthalin/lumbridge/combat_hall/MeleeTutor.kts index e6c2cc8305..5b5e259a7a 100644 --- a/game/src/main/kotlin/content/area/misthalin/lumbridge/combat_hall/MeleeTutor.kts +++ b/game/src/main/kotlin/content/area/misthalin/lumbridge/combat_hall/MeleeTutor.kts @@ -14,6 +14,7 @@ import content.entity.player.bank.ownsItem import content.entity.player.dialogue.* import content.entity.player.dialogue.type.* import content.entity.player.modal.Tab +import content.entity.player.modal.tab npcOperate("Talk-to", "harlan") { npc("Greetings adventurer, I am the Melee combat tutor. Is there anything I can do for you?") @@ -36,9 +37,9 @@ suspend fun SuspendableContext.menu(followUp: String = "") { suspend fun PlayerChoice.meleeCombat(): Unit = option("Tell me about melee combat.") { npc("Well adventurer, the first thing you will need is a sword and a shield appropriate for your level.") // look down talking, look up eyebrow raised then quiet - player["tab"] = Tab.WornEquipment.name + player.tab(Tab.WornEquipment) npc("Make sure to equip your sword and shield. Click on them in your inventory, they will disappear from your inventory and move to your worn items. You can see your worn items in the worn items tab here.") - player["tab"] = Tab.CombatStyles.name + player.tab(Tab.CombatStyles) npc("When you are wielding your sword you will then be able to see the correct options in the combat interface.") npc("There are four different melee styles. Accurate, aggressive, defensive and controlled. Not all weapons will have all four styles though.") player("Interesting, what does each style do?") diff --git a/game/src/main/kotlin/content/area/misthalin/varrock/Delrith.kts b/game/src/main/kotlin/content/area/misthalin/varrock/Delrith.kts index 729a838dd0..f1c3350282 100644 --- a/game/src/main/kotlin/content/area/misthalin/varrock/Delrith.kts +++ b/game/src/main/kotlin/content/area/misthalin/varrock/Delrith.kts @@ -20,7 +20,6 @@ import world.gregs.voidps.engine.entity.character.npc.npcOperate import world.gregs.voidps.engine.entity.character.player.Player import world.gregs.voidps.engine.entity.character.player.skill.Skill import world.gregs.voidps.engine.entity.character.player.skill.level.npcLevelChange -import world.gregs.voidps.engine.entity.item.Item import world.gregs.voidps.engine.entity.obj.GameObjects import world.gregs.voidps.engine.entity.playerDespawn import world.gregs.voidps.engine.event.Context @@ -64,7 +63,7 @@ val targets = listOf( ) enterArea("demon_slayer_stone_circle") { - if (!player.questComplete("demon_slayer") && player["demon_slayer_silverlight", false] && !player.hasClock("demon_slayer_instance_exit")) { + if (!player.questCompleted("demon_slayer") && player["demon_slayer_silverlight", false] && !player.hasClock("demon_slayer_instance_exit")) { cutscene() } } @@ -181,7 +180,7 @@ suspend fun SuspendableContext.cutscene() { delay(1) player.shakeCamera(0, 0, 0, 0, 0) for ((_, target) in targets) { - areaGraphic("demon_slayer_spell_hit", target.add(offset)) + areaGraphic("demon_slayer_spell_impact", target.add(offset)) } delay(2) npcs.index(delrith) @@ -203,11 +202,13 @@ suspend fun SuspendableContext.cutscene() { wizard.clearAnim() wizard.face(delrith) } - npc("denath", """ + npc( + "denath", """ Ha ha ha! At last you are free, my demonic brother! Rest now, and then have your revenge on this pitiful city! - """) + """ + ) for (wizard in wizards) { wizard.face(player) } @@ -298,10 +299,12 @@ fun Context.questComplete() { player.inc("quest_points", 3) DemonSlayerSpell.clear(player) player.softQueue("quest_complete", 1) { - player.sendQuestComplete("Demon Slayer", listOf( + player.questComplete( + "Demon Slayer", "3 Quest Points", - "Silverlight" - ), Item("silverlight")) + "Silverlight", + item = "silverlight" + ) } } diff --git a/game/src/main/kotlin/content/area/misthalin/wizards_tower/Sedridor.kts b/game/src/main/kotlin/content/area/misthalin/wizards_tower/Sedridor.kts index 9180b86040..ca705c3ebb 100644 --- a/game/src/main/kotlin/content/area/misthalin/wizards_tower/Sedridor.kts +++ b/game/src/main/kotlin/content/area/misthalin/wizards_tower/Sedridor.kts @@ -6,7 +6,6 @@ import world.gregs.voidps.engine.entity.character.npc.NPCOption import world.gregs.voidps.engine.entity.character.npc.npcOperate import world.gregs.voidps.engine.entity.character.player.Player import world.gregs.voidps.engine.entity.character.player.name -import world.gregs.voidps.engine.entity.item.Item import world.gregs.voidps.engine.inv.add import world.gregs.voidps.engine.inv.holdsItem import world.gregs.voidps.engine.inv.inventory @@ -17,7 +16,7 @@ import content.entity.player.bank.bank import content.entity.player.bank.ownsItem import content.quest.quest import content.quest.refreshQuestJournal -import content.quest.sendQuestComplete +import content.quest.questComplete import content.skill.runecrafting.EssenceMine import content.entity.player.dialogue.* import content.entity.player.dialogue.type.* @@ -263,10 +262,12 @@ fun Context.questComplete() { player.message("Congratulations, you've completed a quest: Rune Mysteries") player.refreshQuestJournal() player.softQueue("quest_complete", 1) { - player.sendQuestComplete("Rune Mysteries", listOf( + player.questComplete( + "Rune Mysteries", "1 Quest Point", "An Air Talisman", - "Rune Essence Mine Access" - ), Item("air_talisman")) + "Rune Essence Mine Access", + item = "air_talisman" + ) } } \ No newline at end of file diff --git a/game/src/main/kotlin/content/area/wilderness/abyss/AbyssObstacles.kts b/game/src/main/kotlin/content/area/wilderness/abyss/AbyssObstacles.kts index 372b6837b6..d3f1c77e9c 100644 --- a/game/src/main/kotlin/content/area/wilderness/abyss/AbyssObstacles.kts +++ b/game/src/main/kotlin/content/area/wilderness/abyss/AbyssObstacles.kts @@ -131,7 +131,7 @@ objectOperate("Burn-down", "abyss_boil") { delay(6) player["abyss_obstacles"] = 17 val (walkTile, teleTile) = positions[target.tile]!! - areaGraphic("fire_wave_hit", target.tile, height = 128) + areaGraphic("fire_wave_impact", target.tile, height = 128) player.playSound("boil_burst") player.walkToDelay(walkTile) player.message("...and manage to burn it down and get past.", ChatType.Filter) diff --git a/game/src/main/kotlin/content/area/wilderness/abyss/AbyssalRift.kts b/game/src/main/kotlin/content/area/wilderness/abyss/AbyssalRift.kts index d20e138cb6..067b30dfa3 100644 --- a/game/src/main/kotlin/content/area/wilderness/abyss/AbyssalRift.kts +++ b/game/src/main/kotlin/content/area/wilderness/abyss/AbyssalRift.kts @@ -2,12 +2,12 @@ package content.area.wilderness.abyss import world.gregs.voidps.engine.client.message import world.gregs.voidps.engine.entity.obj.objectOperate -import content.quest.questComplete +import content.quest.questCompleted import content.entity.obj.teleportTakeOff teleportTakeOff("Exit-through", "*_rift") { when { - obj.stringId == "cosmic_rift" && !player.questComplete("lost_city") -> { + obj.stringId == "cosmic_rift" && !player.questCompleted("lost_city") -> { player.message("You need to have completed the Lost City Quest to use this rift.") cancel() return@teleportTakeOff @@ -18,12 +18,12 @@ teleportTakeOff("Exit-through", "*_rift") { cancel() return@teleportTakeOff } - obj.stringId == "death_rift" && !player.questComplete("mournings_end_part_2") -> { + obj.stringId == "death_rift" && !player.questCompleted("mournings_end_part_2") -> { player.message("A strange power blocks your exit.") cancel() return@teleportTakeOff } - obj.stringId == "blood_rift" && !player.questComplete("legacy_of_seergaze") -> { + obj.stringId == "blood_rift" && !player.questCompleted("legacy_of_seergaze") -> { player.message("You need to have completed the Legacy of Seergaze quest to use this rift.") cancel() return@teleportTakeOff diff --git a/game/src/main/kotlin/content/area/wilderness/abyss/MageOfZamorak.kts b/game/src/main/kotlin/content/area/wilderness/abyss/MageOfZamorak.kts index 455aa462a8..99d84fcb5d 100644 --- a/game/src/main/kotlin/content/area/wilderness/abyss/MageOfZamorak.kts +++ b/game/src/main/kotlin/content/area/wilderness/abyss/MageOfZamorak.kts @@ -21,7 +21,7 @@ import world.gregs.voidps.engine.queue.ActionPriority import world.gregs.voidps.engine.queue.queue import world.gregs.voidps.type.random import content.entity.player.bank.ownsItem -import content.quest.questComplete +import content.quest.questCompleted import content.entity.player.dialogue.* import content.entity.player.dialogue.type.* import content.entity.npc.shop.openShop @@ -46,7 +46,7 @@ npcOperate("Talk-to", "mage_of_zamorak_wilderness") { return@npcOperate } - if (player.questComplete("rune_mysteries")) { + if (player.questCompleted("rune_mysteries")) { when (player["enter_the_abyss", "unstarted"]) { "unstarted" -> { npc("If you want to talk, this isn't the place for it. Meet me in Varrock's Chaos Temple, by the rune shop. Unless you're here to buy something?") @@ -63,7 +63,7 @@ npcOperate("Talk-to", "mage_of_zamorak_wilderness") { option("Let's see what you're selling.") { player.openShop("mage_of_zamorak") } - option("Could you teleport me to the Abyss?", filter = { player.questComplete("enter_the_abyss") }) { + option("Could you teleport me to the Abyss?", filter = { player.questCompleted("enter_the_abyss") }) { teleport(player, target) } option("Alright, I'll go.") @@ -75,7 +75,7 @@ npcOperate("Talk-to", "mage_of_zamorak_varrock") { npc("How dare you wear such disrespectful attire in this holy place? Remove those immediately if you wish to speak to me.") return@npcOperate } - if (player.questComplete("enter_the_abyss")) { + if (player.questCompleted("enter_the_abyss")) { npc("Ah, you again. What do you want?") choice { aboutAbyss() diff --git a/game/src/main/kotlin/content/entity/combat/Combat.kts b/game/src/main/kotlin/content/entity/combat/Combat.kts index 049e975624..20f0e88121 100644 --- a/game/src/main/kotlin/content/entity/combat/Combat.kts +++ b/game/src/main/kotlin/content/entity/combat/Combat.kts @@ -15,7 +15,7 @@ import world.gregs.voidps.engine.entity.character.player.Player import world.gregs.voidps.engine.entity.character.player.skill.Skill import world.gregs.voidps.engine.entity.characterDespawn import world.gregs.voidps.engine.event.onEvent -import content.entity.combat.hit.characterCombatHit +import content.entity.combat.hit.characterCombatDamage import content.entity.death.characterDeath import content.entity.player.combat.special.specialAttack import content.skill.melee.weapon.attackRange @@ -117,9 +117,9 @@ characterDeath { character -> } } -characterCombatHit { character -> +characterCombatDamage { character -> if (source == character || type == "poison" || type == "disease" || type == "healed") { - return@characterCombatHit + return@characterCombatDamage } if (character.mode !is CombatMovement) { retaliate(character, source) diff --git a/game/src/main/kotlin/content/entity/combat/hit/CombatAttack.kt b/game/src/main/kotlin/content/entity/combat/hit/CombatAttack.kt index c74ccba50f..7f55ef4957 100644 --- a/game/src/main/kotlin/content/entity/combat/hit/CombatAttack.kt +++ b/game/src/main/kotlin/content/entity/combat/hit/CombatAttack.kt @@ -10,7 +10,7 @@ import world.gregs.voidps.engine.event.Events /** * Damage done to a [target] - * Emitted on swing, where [CombatHit] is after the attack delay + * Emitted on swing, where [CombatDamage] is after the attack delay * @param type the combat type, typically: melee, range or magic * @param damage the damage inflicted upon the [target] * @param delay until hit in client ticks diff --git a/game/src/main/kotlin/content/entity/combat/hit/CombatHit.kt b/game/src/main/kotlin/content/entity/combat/hit/CombatDamage.kt similarity index 57% rename from game/src/main/kotlin/content/entity/combat/hit/CombatHit.kt rename to game/src/main/kotlin/content/entity/combat/hit/CombatDamage.kt index faf7b386ef..fb677decb8 100644 --- a/game/src/main/kotlin/content/entity/combat/hit/CombatHit.kt +++ b/game/src/main/kotlin/content/entity/combat/hit/CombatDamage.kt @@ -10,14 +10,14 @@ import world.gregs.voidps.engine.event.Events /** * Damage done by [source] to the emitter - * Used for hit graphics, for effects use [CombatAttack] + * Used for defend graphics, for effects use [CombatAttack] * @param type the combat type, typically: melee, range or magic * @param damage the damage inflicted by the [source] * @param weapon weapon used * @param spell magic spell used * @param special whether weapon special attack was used */ -data class CombatHit( +data class CombatDamage( val source: Character, val type: String, val damage: Int, @@ -31,7 +31,7 @@ data class CombatHit( override val size = 5 override fun parameter(dispatcher: EventDispatcher, index: Int) = when (index) { - 0 -> "${dispatcher.key}_combat_hit" + 0 -> "${dispatcher.key}_combat_damage" 1 -> dispatcher.identifier 2 -> weapon.id 3 -> type @@ -40,15 +40,15 @@ data class CombatHit( } } -fun combatHit(weapon: String = "*", type: String = "*", spell: String = "*", handler: suspend CombatHit.(Player) -> Unit) { - Events.handle("player_combat_hit", "player", weapon, type, spell, handler = handler) +fun combatDamage(weapon: String = "*", type: String = "*", spell: String = "*", handler: suspend CombatDamage.(Player) -> Unit) { + Events.handle("player_combat_damage", "player", weapon, type, spell, handler = handler) } -fun npcCombatHit(npc: String = "*", weapon: String = "*", type: String = "*", spell: String = "*", handler: suspend CombatHit.(NPC) -> Unit) { - Events.handle("npc_combat_hit", npc, weapon, type, spell, handler = handler) +fun npcCombatDamage(npc: String = "*", weapon: String = "*", type: String = "*", spell: String = "*", handler: suspend CombatDamage.(NPC) -> Unit) { + Events.handle("npc_combat_damage", npc, weapon, type, spell, handler = handler) } -fun characterCombatHit(weapon: String = "*", type: String = "*", spell: String = "*", handler: suspend CombatHit.(Character) -> Unit) { - combatHit(weapon, type, spell, handler) - npcCombatHit("*", weapon, type, spell, handler) +fun characterCombatDamage(weapon: String = "*", type: String = "*", spell: String = "*", handler: suspend CombatDamage.(Character) -> Unit) { + combatDamage(weapon, type, spell, handler) + npcCombatDamage("*", weapon, type, spell, handler) } \ No newline at end of file diff --git a/game/src/main/kotlin/content/entity/combat/hit/CombatHitsplats.kts b/game/src/main/kotlin/content/entity/combat/hit/CombatHitsplats.kts index 38fc5de100..72b8e47380 100644 --- a/game/src/main/kotlin/content/entity/combat/hit/CombatHitsplats.kts +++ b/game/src/main/kotlin/content/entity/combat/hit/CombatHitsplats.kts @@ -14,9 +14,9 @@ import kotlin.math.floor val definitions: SpellDefinitions by inject() -characterCombatHit { character -> +characterCombatDamage { character -> if (damage < 0 || type == "magic" && definitions.get(spell).maxHit == -1 || type == "healed") { - return@characterCombatHit + return@characterCombatDamage } var damage = damage var soak = 0 @@ -53,7 +53,7 @@ characterCombatHit { character -> character.levels.drain(Skill.Constitution, damage) } -characterCombatHit { character -> +characterCombatDamage { character -> if (damage < 0) { character.hit( source = source, diff --git a/game/src/main/kotlin/content/entity/combat/hit/Hit.kt b/game/src/main/kotlin/content/entity/combat/hit/Hit.kt index 61d47b5b4c..2c104c0b2c 100644 --- a/game/src/main/kotlin/content/entity/combat/hit/Hit.kt +++ b/game/src/main/kotlin/content/entity/combat/hit/Hit.kt @@ -145,7 +145,7 @@ fun Character.directHit(source: Character, damage: Int, type: String = "damage", if (source.dead) { return } - emit(CombatHit(source, type, damage, weapon, spell, special)) + emit(CombatDamage(source, type, damage, weapon, spell, special)) if (source["debug", false] || this["debug", false]) { val player = if (this["debug", false] && this is Player) this else source as Player val message = "Damage: $damage ($type, ${if (weapon.isEmpty()) "unarmed" else weapon.id})" diff --git a/game/src/main/kotlin/content/entity/death/PlayerDeath.kts b/game/src/main/kotlin/content/entity/death/PlayerDeath.kts index 2556e4ad99..e4014f7931 100644 --- a/game/src/main/kotlin/content/entity/death/PlayerDeath.kts +++ b/game/src/main/kotlin/content/entity/death/PlayerDeath.kts @@ -96,7 +96,7 @@ fun dropItems(player: Player, killer: Character?, tile: Tile, inWilderness: Bool } } // Drop everything - drop(player, Item("bones", 1), tile, inWilderness, killer) + drop(player, Item("bones"), tile, inWilderness, killer) drop(player, player.inventory, tile, inWilderness, killer) drop(player, player.equipment, tile, inWilderness, killer) // Clear everything diff --git a/game/src/main/kotlin/content/entity/player/combat/special/SpecialAttackHit.kt b/game/src/main/kotlin/content/entity/player/combat/special/SpecialAttackDamage.kt similarity index 58% rename from game/src/main/kotlin/content/entity/player/combat/special/SpecialAttackHit.kt rename to game/src/main/kotlin/content/entity/player/combat/special/SpecialAttackDamage.kt index 4556e5fbd1..4fd21bb26d 100644 --- a/game/src/main/kotlin/content/entity/player/combat/special/SpecialAttackHit.kt +++ b/game/src/main/kotlin/content/entity/player/combat/special/SpecialAttackDamage.kt @@ -6,17 +6,21 @@ import world.gregs.voidps.engine.event.Event import world.gregs.voidps.engine.event.EventDispatcher import world.gregs.voidps.engine.event.Events -data class SpecialAttackHit(val id: String, val target: Character, val damage: Int) : Event { +data class SpecialAttackDamage( + val id: String, + val target: Character, + val damage: Int +) : Event { override val size = 3 override fun parameter(dispatcher: EventDispatcher, index: Int) = when (index) { - 0 -> "special_attack_hit" + 0 -> "special_attack_damage" 1 -> id 2 -> damage >= 0 else -> null } } -fun specialAttackHit(id: String, noHit: Boolean = true, handler: suspend SpecialAttackHit.(Player) -> Unit) { - Events.handle("special_attack_hit", id, if (noHit) true else "*", handler = handler) +fun specialAttackDamage(id: String, noHit: Boolean = true, handler: suspend SpecialAttackDamage.(Player) -> Unit) { + Events.handle("special_attack_damage", id, if (noHit) true else "*", handler = handler) } \ No newline at end of file diff --git a/game/src/main/kotlin/content/entity/player/combat/special/SpecialAttacks.kts b/game/src/main/kotlin/content/entity/player/combat/special/SpecialAttacks.kts index c50c329c2b..b0f9442b92 100644 --- a/game/src/main/kotlin/content/entity/player/combat/special/SpecialAttacks.kts +++ b/game/src/main/kotlin/content/entity/player/combat/special/SpecialAttacks.kts @@ -29,8 +29,7 @@ specialAttack { player -> player.playSound("${id}_special") val damage = player.hit(target) if (damage >= 0) { - target.anim("${id}_hit") - target.gfx("${id}_hit") + target.gfx("${id}_impact") } - player.emit(SpecialAttackHit(id, target, damage)) + player.emit(SpecialAttackDamage(id, target, damage)) } diff --git a/game/src/main/kotlin/content/entity/player/command/admin/AdminCommands.kts b/game/src/main/kotlin/content/entity/player/command/admin/AdminCommands.kts index 759f1e1549..0c5f02c60e 100644 --- a/game/src/main/kotlin/content/entity/player/command/admin/AdminCommands.kts +++ b/game/src/main/kotlin/content/entity/player/command/admin/AdminCommands.kts @@ -95,9 +95,9 @@ adminCommand("tele (x) (y) [level]", "teleport to given coordinates or area name val int = parts[0].toIntOrNull() when { int == null -> when (content.lowercase()) { - "draynor" -> player.tele(3086, 3248) - "varrock" -> player.tele(3212, 3429) - "lumbridge" -> player.tele(3222, 3219) + "draynor" -> player.tele(3086, 3248, 0) + "varrock" -> player.tele(3212, 3429, 0) + "lumbridge" -> player.tele(3222, 3219, 0) else -> player.tele(areas[content]) } parts.size == 1 -> player.tele(Region(int).tile.add(32, 32)) @@ -205,7 +205,7 @@ adminCommand("give (item-id) [amount] (player-name)", "spawn item in another pla } } -modCommand("find (item name)", "search the id of an item", aliases = listOf("search")) { +modCommand("find (content-name)", "search for a piece of content by name", aliases = listOf("search")) { val search = content.lowercase() var found = 0 player.message("===== Items =====", ChatType.Console) @@ -214,6 +214,15 @@ modCommand("find (item name)", "search the id of an item", aliases = listOf("sea found += search(player, get(), search) { it.name } player.message("===== NPCs =====", ChatType.Console) found += search(player, get(), search) { it.name } + player.message("===== Commands =====", ChatType.Console) + for (command in Command.adminCommands) { + if (command.startsWith(Colours.BLUE.toTag()) && command.contains(content, ignoreCase = true)) { + val colourless = command.removePrefix(Colours.BLUE.toTag()).removeSuffix("") + val cmd = colourless.substringBefore("(").substringBefore("[").trim() + player.message("[${cmd}] - usage: $colourless", ChatType.Console) + found++ + } + } player.message("$found results found for '$search'", ChatType.Console) } diff --git a/game/src/main/kotlin/content/entity/player/command/debug/DebugCommands.kts b/game/src/main/kotlin/content/entity/player/command/debug/DebugCommands.kts index 3dfaed5640..e687c69a23 100644 --- a/game/src/main/kotlin/content/entity/player/command/debug/DebugCommands.kts +++ b/game/src/main/kotlin/content/entity/player/command/debug/DebugCommands.kts @@ -37,7 +37,7 @@ import world.gregs.voidps.type.Zone import content.entity.player.dialogue.sendLines import content.entity.player.dialogue.type.npc import content.entity.gfx.areaGraphic -import content.quest.sendQuestJournal +import content.quest.questJournal import kotlin.system.measureNanoTime import kotlin.system.measureTimeMillis @@ -50,7 +50,7 @@ modCommand("test") { println("Facing ${player.tile.delta(player.visuals.face.targetX, player.visuals.face.targetY)}") } -modCommand("commands", aliases = listOf("help")) { +modCommand("commands") { val commands = if (player.isAdmin()) Command.adminCommands else Command.modCommands val list = listOf( "Commands list with descriptions and usage instructions in the format:", @@ -58,7 +58,34 @@ modCommand("commands", aliases = listOf("help")) { "command description", "" ) - player.sendQuestJournal("Commands List", list + commands) + player.questJournal("Commands List", list + commands) +} + +modCommand("help (command-name)", "gives more information about a command") { + // TODO find a way to automate this. + when (content) { + "reload" -> { + player.message("Reload configuration files for the game server.", ChatType.Console) + player.message("config-names:", ChatType.Console) + player.message("books, stairs, songs, objects, nav graph, npcs, areas, object defs, emotes, anims", ChatType.Console) + player.message("invs, graphics, npc defs, item-on-item, sounds, quests, midi, vars, music, interfaces", ChatType.Console) + player.message("spells, patrols, prayers, drops, client scripts, settings", ChatType.Console) + } + "unlock" -> { + player.message("Unlock content of a specific type.", ChatType.Console) + player.message("activity-type:", ChatType.Console) + player.message("music, tasks, emotes, quests, or blank to unlock all.", ChatType.Console) + } + "find" -> { + player.message("Find the string or integer id of a piece of content.", ChatType.Console) + player.message("content-types:", ChatType.Console) + player.message("items, objects, npcs, commands", ChatType.Console) + } + else -> { + player.message("No help info found for command '${content}'.", ChatType.Console) + player.message("Enter 'commands' for full list of commands.", ChatType.Console) + } + } } Command.adminCommands.add("${Colours.PURPLE.toTag()}====== Testing Commands ======") diff --git a/game/src/main/kotlin/content/entity/player/dialogue/type/LevelUp.kts b/game/src/main/kotlin/content/entity/player/dialogue/type/LevelUp.kts index bdbe5d799e..35134fb3e6 100644 --- a/game/src/main/kotlin/content/entity/player/dialogue/type/LevelUp.kts +++ b/game/src/main/kotlin/content/entity/player/dialogue/type/LevelUp.kts @@ -10,7 +10,7 @@ import world.gregs.voidps.engine.entity.character.player.skill.exp.experience import world.gregs.voidps.engine.entity.character.player.skill.level.MaxLevelChanged import world.gregs.voidps.engine.entity.character.player.skill.level.maxLevelChange import world.gregs.voidps.engine.queue.weakQueue -import content.entity.combat.hit.combatHit +import content.entity.combat.hit.combatDamage import content.entity.sound.playJingle experience { player -> @@ -47,7 +47,7 @@ maxLevelChange { player -> } } -combatHit { player -> +combatDamage { player -> if (!(player.menu ?: player.dialogue).isNullOrBlank()) { player.closeInterfaces() } diff --git a/game/src/main/kotlin/content/entity/player/dialogue/type/MakeAmount.kt b/game/src/main/kotlin/content/entity/player/dialogue/type/MakeAmount.kt index d8a89e1d1b..b3aa24e5d6 100644 --- a/game/src/main/kotlin/content/entity/player/dialogue/type/MakeAmount.kt +++ b/game/src/main/kotlin/content/entity/player/dialogue/type/MakeAmount.kt @@ -20,9 +20,9 @@ suspend fun Context.makeAmount( allowAll: Boolean = true, names: List? = null ): Pair { - val result = makeAmountIndex(items, type, maximum, text, allowAll, names) - val id = items.getOrNull(result.first) ?: "" - return id to result.second + val (index, amount) = makeAmountIndex(items, type, maximum, text, allowAll, names) + val id = items.getOrNull(index) ?: "" + return id to amount } suspend fun Context.makeAmountIndex( @@ -53,7 +53,7 @@ suspend fun Context.makeAmountIndex( private fun setItemOptions(player: Player, items: List, names: List?) { val definitions: ItemDefinitions = get() - repeat(10) { index -> + for (index in 0 until 10) { val item = definitions.get(items.getOrNull(index) ?: "") player["skill_creation_item_$index"] = item.id if (names != null && names.indices.contains(index)) { diff --git a/game/src/main/kotlin/content/entity/player/dialogue/type/QuestStart.kt b/game/src/main/kotlin/content/entity/player/dialogue/type/QuestStart.kt index 064b89811f..0e79945460 100644 --- a/game/src/main/kotlin/content/entity/player/dialogue/type/QuestStart.kt +++ b/game/src/main/kotlin/content/entity/player/dialogue/type/QuestStart.kt @@ -12,7 +12,7 @@ import world.gregs.voidps.engine.get import world.gregs.voidps.engine.suspend.SuspendableContext import world.gregs.voidps.engine.suspend.StringSuspension import content.quest.quest -import content.quest.questComplete +import content.quest.questCompleted private const val QUEST_START_ID = "quest_intro" @@ -21,7 +21,7 @@ suspend fun SuspendableContext.startQuest(questId: String): Boolean { val questDefinitions: QuestDefinitions = get() val quest = questDefinitions.getOrNull(questId) check(quest != null) { "Unable to find quest with id $questId $player" } - val completed = player.questComplete(questId) + val completed = player.questCompleted(questId) player.interfaces.sendVisibility("quest_intro", "start_choice_layer", !completed) player.interfaces.sendVisibility("quest_intro", "progress_status_layer", completed) val status = when (player.quest(questId)) { diff --git a/game/src/main/kotlin/content/entity/player/dialogue/type/Statement.kt b/game/src/main/kotlin/content/entity/player/dialogue/type/Statement.kt index 98ab441450..d1891a3a9b 100644 --- a/game/src/main/kotlin/content/entity/player/dialogue/type/Statement.kt +++ b/game/src/main/kotlin/content/entity/player/dialogue/type/Statement.kt @@ -12,7 +12,7 @@ import content.entity.player.dialogue.sendLines private const val MAXIMUM_STATEMENT_SIZE = 5 suspend fun SuspendableContext.statement(text: String, clickToContinue: Boolean = true) { - val lines = if (text.contains("\n")) text.trimIndent().lines() else get().get("q8_full").splitLines(text, 470) + val lines = if (text.isBlank()) listOf("") else if (text.contains("\n")) text.trimIndent().lines() else get().get("q8_full").splitLines(text, 470) check(lines.size <= MAXIMUM_STATEMENT_SIZE) { "Maximum statement lines exceeded ${lines.size} for $player" } val id = getInterfaceId(lines.size, clickToContinue) check(player.open(id)) { "Unable to open statement dialogue $id for $player" } diff --git a/game/src/main/kotlin/content/entity/player/inv/item/ItemPickup.kts b/game/src/main/kotlin/content/entity/player/inv/item/take/ItemTake.kts similarity index 77% rename from game/src/main/kotlin/content/entity/player/inv/item/ItemPickup.kts rename to game/src/main/kotlin/content/entity/player/inv/item/take/ItemTake.kts index c5a7467e21..1cdbb4119a 100644 --- a/game/src/main/kotlin/content/entity/player/inv/item/ItemPickup.kts +++ b/game/src/main/kotlin/content/entity/player/inv/item/take/ItemTake.kts @@ -1,4 +1,4 @@ -package content.entity.player.inv.item +package content.entity.player.inv.item.take import com.github.michaelbull.logging.InlineLogger import world.gregs.voidps.engine.client.message @@ -18,7 +18,13 @@ val logger = InlineLogger() floorItemOperate("Take") { approachRange(-1) - if (player.inventory.isFull() && (!player.inventory.stackable(target.id) || !player.inventory.contains(target.id))) { + val takeable = Takeable(target.id) + player.emit(takeable) + if (takeable.cancelled) { + return@floorItemOperate + } + val item = takeable.item + if (player.inventory.isFull() && (!player.inventory.stackable(item) || !player.inventory.contains(item))) { player.inventoryFull() return@floorItemOperate } @@ -29,7 +35,7 @@ floorItemOperate("Take") { player.inventory.transaction { val freeIndex = inventory.freeIndex() - add(target.id, target.amount) + add(item, target.amount) if (target.charges > 0) { setCharge(freeIndex, target.charges) } @@ -40,16 +46,17 @@ floorItemOperate("Take") { player.face(target.tile.delta(player.tile)) player.anim("take") } - player.playSound("pickup_item") + player.playSound("take_item") + player.emit(Taken(target, item)) } is TransactionError.Full -> player.inventoryFull() - else -> logger.warn { "Error picking up item $target ${player.inventory.transaction.error}" } + else -> logger.warn { "Error taking item $target ${player.inventory.transaction.error}" } } } npcOperateFloorItem("Take") { if (!floorItems.remove(target)) { - logger.warn { "$npc unable to pick up $target." } + logger.warn { "$npc unable to take $target." } } if (npc.id == "ash_cleaner") { npc.anim("cleaner_sweeping") diff --git a/game/src/main/kotlin/content/entity/player/inv/item/take/Takeable.kt b/game/src/main/kotlin/content/entity/player/inv/item/take/Takeable.kt new file mode 100644 index 0000000000..9e50a92fff --- /dev/null +++ b/game/src/main/kotlin/content/entity/player/inv/item/take/Takeable.kt @@ -0,0 +1,26 @@ +package content.entity.player.inv.item.take + +import world.gregs.voidps.engine.entity.character.player.Player +import world.gregs.voidps.engine.event.CancellableEvent +import world.gregs.voidps.engine.event.EventDispatcher +import world.gregs.voidps.engine.event.Events + +/** + * Checks that an item can be taken off of the floor. Continues unless [cancelled]. + */ +data class Takeable(var item: String) : CancellableEvent() { + + override val size = 2 + + override fun parameter(dispatcher: EventDispatcher, index: Int) = when (index) { + 0 -> "can_take" + 1 -> item + else -> null + } +} + +fun canTake(vararg items: String = arrayOf("*"), handler: Takeable.(Player) -> Unit) { + for (item in items) { + Events.handle("can_take", item, handler = handler) + } +} \ No newline at end of file diff --git a/game/src/main/kotlin/content/entity/player/inv/item/take/Taken.kt b/game/src/main/kotlin/content/entity/player/inv/item/take/Taken.kt new file mode 100644 index 0000000000..b231ff0e29 --- /dev/null +++ b/game/src/main/kotlin/content/entity/player/inv/item/take/Taken.kt @@ -0,0 +1,28 @@ +package content.entity.player.inv.item.take + +import world.gregs.voidps.engine.entity.character.player.Player +import world.gregs.voidps.engine.entity.item.floor.FloorItem +import world.gregs.voidps.engine.event.CancellableEvent +import world.gregs.voidps.engine.event.EventDispatcher +import world.gregs.voidps.engine.event.Events + +/** + * @param floorItem The item which was taken off of the floor + * @param item The item which was given to the player + */ +data class Taken(val floorItem: FloorItem, val item: String) : CancellableEvent() { + + override val size = 2 + + override fun parameter(dispatcher: EventDispatcher, index: Int) = when (index) { + 0 -> "taken" + 1 -> floorItem.id + else -> null + } +} + +fun taken(vararg items: String = arrayOf("*"), handler: Taken.(Player) -> Unit) { + for (item in items) { + Events.handle("taken", item, handler = handler) + } +} \ No newline at end of file diff --git a/game/src/main/kotlin/content/entity/player/modal/Tab.kt b/game/src/main/kotlin/content/entity/player/modal/Tab.kt index ea9cd95079..e19fe3af45 100644 --- a/game/src/main/kotlin/content/entity/player/modal/Tab.kt +++ b/game/src/main/kotlin/content/entity/player/modal/Tab.kt @@ -1,5 +1,7 @@ package content.entity.player.modal +import world.gregs.voidps.engine.entity.character.player.Player + enum class Tab { CombatStyles, TaskSystem, @@ -16,4 +18,8 @@ enum class Tab { Emotes, MusicPlayer, Notes; +} + +fun Player.tab(tab: Tab) { + this["tab"] = tab.name } \ No newline at end of file diff --git a/game/src/main/kotlin/content/entity/player/price/PriceChecker.kts b/game/src/main/kotlin/content/entity/player/price/PriceChecker.kts index 497a84f45c..032238742c 100644 --- a/game/src/main/kotlin/content/entity/player/price/PriceChecker.kts +++ b/game/src/main/kotlin/content/entity/player/price/PriceChecker.kts @@ -19,6 +19,7 @@ import content.entity.player.bank.noted import content.social.trade.offer import content.entity.player.dialogue.type.intEntry import content.entity.player.modal.Tab +import content.entity.player.modal.tab /* Price checker interface @@ -59,7 +60,7 @@ interfaceClose("price_checker") { player -> */ interfaceOpen("price_checker_side") { player -> - player["tab"] = Tab.Inventory.name + player.tab(Tab.Inventory) player.interfaceOptions.send(id, "items") player.interfaceOptions.unlockAll(id, "items", 0 until 28) player.sendInventory(player.inventory) diff --git a/game/src/main/kotlin/content/quest/Quest.kt b/game/src/main/kotlin/content/quest/Quest.kt index 3c4004c6de..94f7dac6ad 100644 --- a/game/src/main/kotlin/content/quest/Quest.kt +++ b/game/src/main/kotlin/content/quest/Quest.kt @@ -20,7 +20,7 @@ val quests = listOf( fun Player.quest(name: String): String = this[name, "unstarted"] -fun Player.questComplete(name: String): Boolean = quest(name) == "completed" +fun Player.questCompleted(name: String): Boolean = quest(name) == "completed" fun Player.refreshQuestJournal() { sendScript("quest_journal_refresh") @@ -28,7 +28,7 @@ fun Player.refreshQuestJournal() { private const val QUEST_SCROLL_ID = "quest_scroll" -fun Player.sendQuestJournal(name: String, lines: List) { +fun Player.questJournal(name: String, lines: List) { if (!interfaces.open(QUEST_SCROLL_ID)) { return } @@ -40,7 +40,11 @@ fun Player.sendQuestJournal(name: String, lines: List) { } } -fun Player.sendQuestComplete(name: String, lines: List, item: Item = Item.EMPTY) { +fun Player.questComplete(name: String, vararg lines: String, item: String = "") { + questComplete(name, lines.toList(), if (item == "") Item.EMPTY else Item(item)) +} + +fun Player.questComplete(name: String, lines: List, item: Item = Item.EMPTY) { open("quest_complete") interfaces.sendText("quest_complete", "quest_name", "You have completed $name!") interfaces.sendText("quest_complete", "quest_points", get("quest_points", 0).toString()) @@ -52,7 +56,7 @@ fun Player.sendQuestComplete(name: String, lines: List, item: Item = Ite } } -fun Player.sendLetterScroll(name: String, lines: List) { +fun Player.letterScroll(name: String, lines: List) { if (!interfaces.open("letter_scroll")) { return } @@ -64,7 +68,7 @@ fun Player.sendLetterScroll(name: String, lines: List) { } } -fun Player.sendWomScroll(name: String, lines: List) { +fun Player.wiseOldManScroll(name: String, lines: List) { if (!interfaces.open("wise_old_man_scroll")) { return } @@ -74,7 +78,7 @@ fun Player.sendWomScroll(name: String, lines: List) { } } -fun Player.sendMessageScroll(lines: List, handwriting: Boolean = false) { +fun Player.messageScroll(lines: List, handwriting: Boolean = false) { val id = "message_scroll${if (handwriting) "_handwriting" else ""}" if (!interfaces.open(id)) { return diff --git a/game/src/main/kotlin/content/quest/free/cooks_assistant/CooksAssistant.kts b/game/src/main/kotlin/content/quest/free/cooks_assistant/CooksAssistant.kts index e1a5298de0..6174c567f9 100644 --- a/game/src/main/kotlin/content/quest/free/cooks_assistant/CooksAssistant.kts +++ b/game/src/main/kotlin/content/quest/free/cooks_assistant/CooksAssistant.kts @@ -4,7 +4,7 @@ import world.gregs.voidps.engine.client.ui.interfaceSlot import world.gregs.voidps.engine.inv.holdsItem import content.entity.player.bank.bank import content.quest.quest -import content.quest.sendQuestJournal +import content.quest.questJournal interfaceSlot(component = "journals", id = "quest_journals", itemSlot = 1) { val lines = when (player.quest("cooks_assistant")) { @@ -79,5 +79,5 @@ interfaceSlot(component = "journals", id = "quest_journals", itemSlot = 1) { "kitchen of Lumbridge Castle." ) } - player.sendQuestJournal("Cook's Aassistant", lines) + player.questJournal("Cook's Aassistant", lines) } \ No newline at end of file diff --git a/game/src/main/kotlin/content/quest/free/demon_slayer/DemonSlayer.kts b/game/src/main/kotlin/content/quest/free/demon_slayer/DemonSlayer.kts index 006e716697..a0cdbde628 100644 --- a/game/src/main/kotlin/content/quest/free/demon_slayer/DemonSlayer.kts +++ b/game/src/main/kotlin/content/quest/free/demon_slayer/DemonSlayer.kts @@ -4,7 +4,7 @@ import world.gregs.voidps.engine.client.ui.interfaceSlot import world.gregs.voidps.engine.entity.character.player.Player import world.gregs.voidps.engine.inv.inventory import content.quest.quest -import content.quest.sendQuestJournal +import content.quest.questJournal interfaceSlot(component = "journals", id = "quest_journals", itemSlot = 2) { val lines = when (player.quest("demon_slayer")) { @@ -57,7 +57,7 @@ interfaceSlot(component = "journals", id = "quest_journals", itemSlot = 2) { ) else -> listOf() } - player.sendQuestJournal("Demon Slayer", lines) + player.questJournal("Demon Slayer", lines) } fun listKeys( diff --git a/game/src/main/kotlin/content/quest/free/dorics_quest/DoricsQuest.kts b/game/src/main/kotlin/content/quest/free/dorics_quest/DoricsQuest.kts index 287dc0850b..176f6d0989 100644 --- a/game/src/main/kotlin/content/quest/free/dorics_quest/DoricsQuest.kts +++ b/game/src/main/kotlin/content/quest/free/dorics_quest/DoricsQuest.kts @@ -5,7 +5,7 @@ import world.gregs.voidps.engine.client.ui.interfaceSlot import world.gregs.voidps.engine.entity.character.player.Player import world.gregs.voidps.engine.inv.inventory import content.quest.quest -import content.quest.sendQuestJournal +import content.quest.questJournal interfaceSlot(component = "journals", id = "quest_journals", itemSlot = 3) { val lines = when (player.quest("dorics_quest")) { @@ -33,7 +33,7 @@ interfaceSlot(component = "journals", id = "quest_journals", itemSlot = 3) { "There aren't any requirements but Level 15 Mining will help" ) } - player.sendQuestJournal("Doric's Quest", lines) + player.questJournal("Doric's Quest", lines) } fun requiredItem(player: Player, item: String, required: Int): String { diff --git a/game/src/main/kotlin/content/quest/free/gunnars_ground/GunnarsGround.kts b/game/src/main/kotlin/content/quest/free/gunnars_ground/GunnarsGround.kts index cb1d5b1227..5567f50a9d 100644 --- a/game/src/main/kotlin/content/quest/free/gunnars_ground/GunnarsGround.kts +++ b/game/src/main/kotlin/content/quest/free/gunnars_ground/GunnarsGround.kts @@ -5,8 +5,8 @@ import world.gregs.voidps.engine.entity.playerSpawn import world.gregs.voidps.engine.inv.holdsItem import content.entity.player.inv.inventoryItem import content.quest.quest -import content.quest.sendLetterScroll -import content.quest.sendQuestJournal +import content.quest.letterScroll +import content.quest.questJournal playerSpawn { player -> player.sendVariable("gudrun_after_quest") @@ -22,7 +22,7 @@ playerSpawn { player -> } inventoryItem("Read", "gunnars_ground", "inventory") { - player.sendLetterScroll("Gunnar's Ground", listOf( + player.letterScroll("Gunnar's Ground", listOf( "Our people dwelt on mountains steeped in lore,", "A mighty tribe as harsh as any beast", "Who then, in face of madness swept to war,", @@ -296,5 +296,5 @@ interfaceSlot(component = "journals", id = "quest_journals", itemSlot = 17) { "just outside the barbarian village." ) } - player.sendQuestJournal("Gunnar's Ground", lines) + player.questJournal("Gunnar's Ground", lines) } diff --git a/game/src/main/kotlin/content/quest/free/rune_mysteries/RuneMysteries.kts b/game/src/main/kotlin/content/quest/free/rune_mysteries/RuneMysteries.kts index 1ed75685e5..80b876882a 100644 --- a/game/src/main/kotlin/content/quest/free/rune_mysteries/RuneMysteries.kts +++ b/game/src/main/kotlin/content/quest/free/rune_mysteries/RuneMysteries.kts @@ -3,7 +3,7 @@ package content.quest.free.rune_mysteries import world.gregs.voidps.engine.client.ui.interfaceSlot import world.gregs.voidps.engine.inv.holdsItem import content.quest.quest -import content.quest.sendQuestJournal +import content.quest.questJournal interfaceSlot(component = "journals", id = "quest_journals", itemSlot = 13) { val lines = when (player.quest("rune_mysteries")) { @@ -118,5 +118,5 @@ interfaceSlot(component = "journals", id = "quest_journals", itemSlot = 13) { "Lumbridgeupstairs in Lumbridge Castle." ) } - player.sendQuestJournal("Rune Mysteries", lines) + player.questJournal("Rune Mysteries", lines) } \ No newline at end of file diff --git a/game/src/main/kotlin/content/quest/free/the_knights_sword/TheKnightsSword.kts b/game/src/main/kotlin/content/quest/free/the_knights_sword/TheKnightsSword.kts index e2422761f6..fe5156c51e 100644 --- a/game/src/main/kotlin/content/quest/free/the_knights_sword/TheKnightsSword.kts +++ b/game/src/main/kotlin/content/quest/free/the_knights_sword/TheKnightsSword.kts @@ -4,7 +4,7 @@ import world.gregs.voidps.engine.client.ui.interfaceSlot import world.gregs.voidps.engine.inv.holdsItem import content.entity.player.bank.ownsItem import content.quest.quest -import content.quest.sendQuestJournal +import content.quest.questJournal interfaceSlot(component = "journals", id = "quest_journals", itemSlot = 8) { val lines = when (player.quest("the_knights_sword")) { @@ -96,5 +96,5 @@ interfaceSlot(component = "journals", id = "quest_journals", itemSlot = 8) { "and to be unafraid of Level 57 Ice Warriors." ) } - player.sendQuestJournal("The Knight's Sword", lines) + player.questJournal("The Knight's Sword", lines) } \ No newline at end of file diff --git a/game/src/main/kotlin/content/quest/free/the_restless_ghost/TheRestlessGhost.kts b/game/src/main/kotlin/content/quest/free/the_restless_ghost/TheRestlessGhost.kts index 4381386e4b..d49f82d3cc 100644 --- a/game/src/main/kotlin/content/quest/free/the_restless_ghost/TheRestlessGhost.kts +++ b/game/src/main/kotlin/content/quest/free/the_restless_ghost/TheRestlessGhost.kts @@ -3,7 +3,7 @@ package content.quest.free.the_restless_ghost import world.gregs.voidps.engine.client.ui.interfaceSlot import content.entity.player.bank.ownsItem import content.quest.quest -import content.quest.sendQuestJournal +import content.quest.questJournal interfaceSlot(component = "journals", id = "quest_journals", itemSlot = 11) { val lines = when (player.quest("the_restless_ghost")) { @@ -89,5 +89,5 @@ interfaceSlot(component = "journals", id = "quest_journals", itemSlot = 11) { "church next to Lumbridge Castle." ) } - player.sendQuestJournal("The Restless Ghost", lines) + player.questJournal("The Restless Ghost", lines) } \ No newline at end of file diff --git a/game/src/main/kotlin/content/quest/member/druidic_ritual/DruidicRitual.kts b/game/src/main/kotlin/content/quest/member/druidic_ritual/DruidicRitual.kts index 85c46650f7..d35e97ef21 100644 --- a/game/src/main/kotlin/content/quest/member/druidic_ritual/DruidicRitual.kts +++ b/game/src/main/kotlin/content/quest/member/druidic_ritual/DruidicRitual.kts @@ -2,7 +2,7 @@ package content.quest.member.druidic_ritual import world.gregs.voidps.engine.client.ui.interfaceSlot import content.quest.quest -import content.quest.sendQuestJournal +import content.quest.questJournal interfaceSlot(component = "journals", id = "quest_journals", itemSlot = 33) { val lines = when (player.quest("druidic_ritual")) { @@ -36,5 +36,5 @@ interfaceSlot(component = "journals", id = "quest_journals", itemSlot = 33) { "I can start this quest by talking to Kaqemeex at the Taverley Stone Circle." ) } - player.sendQuestJournal("Druidic Ritual", lines) + player.questJournal("Druidic Ritual", lines) } diff --git a/game/src/main/kotlin/content/quest/miniquest/alfred_grimhands_barcrawl/AlfredGrimhandsBarCrawl.kts b/game/src/main/kotlin/content/quest/miniquest/alfred_grimhands_barcrawl/AlfredGrimhandsBarCrawl.kts index 0a4d2ef1c2..1f44de38c8 100644 --- a/game/src/main/kotlin/content/quest/miniquest/alfred_grimhands_barcrawl/AlfredGrimhandsBarCrawl.kts +++ b/game/src/main/kotlin/content/quest/miniquest/alfred_grimhands_barcrawl/AlfredGrimhandsBarCrawl.kts @@ -5,7 +5,7 @@ import world.gregs.voidps.engine.client.ui.chat.Colours import world.gregs.voidps.engine.client.ui.chat.toTag import world.gregs.voidps.engine.event.Context import world.gregs.voidps.engine.entity.character.player.Player -import content.quest.sendMessageScroll +import content.quest.messageScroll import content.entity.player.inv.inventoryItem inventoryItem("Read", "barcrawl_card") { @@ -14,7 +14,7 @@ inventoryItem("Read", "barcrawl_card") { player.message("You are too drunk to be able to read the barcrawl card.") return@inventoryItem } - player.sendMessageScroll( + player.messageScroll( listOf( "${Colours.BLUE.toTag()}The Official Alfred Grimhand Barcrawl!", "", diff --git a/game/src/main/kotlin/content/skill/agility/course/WildernessCourse.kts b/game/src/main/kotlin/content/skill/agility/course/WildernessCourse.kts index e9e9b35160..e90acb7ff6 100644 --- a/game/src/main/kotlin/content/skill/agility/course/WildernessCourse.kts +++ b/game/src/main/kotlin/content/skill/agility/course/WildernessCourse.kts @@ -192,7 +192,7 @@ objectOperate("Walk-across", "wilderness_log_balance") { delay() player.walkOverDelay(Tile(2998, 10345)) player.damage((player.levels.get(Skill.Constitution) * 0.15).toInt() + 10) - player.playSound("male_hit_1", delay = 20) + player.playSound("male_defend_1", delay = 20) } if (success || Settings["agility.disableFailLapSkip", false]) { player.agilityStage(4) diff --git a/game/src/main/kotlin/content/skill/crafting/Jewellery.kts b/game/src/main/kotlin/content/skill/crafting/Jewellery.kts index 790775aa2f..3039f70a70 100644 --- a/game/src/main/kotlin/content/skill/crafting/Jewellery.kts +++ b/game/src/main/kotlin/content/skill/crafting/Jewellery.kts @@ -1,5 +1,8 @@ package content.skill.crafting +import com.github.michaelbull.logging.InlineLogger +import content.entity.player.dialogue.type.intEntry +import content.skill.slayer.unlocked import net.pearx.kasechange.toLowerSpaceCase import world.gregs.voidps.engine.client.message import world.gregs.voidps.engine.client.sendScript @@ -11,23 +14,24 @@ import world.gregs.voidps.engine.client.ui.interfaceOption import world.gregs.voidps.engine.client.ui.open import world.gregs.voidps.engine.data.definition.data.Jewellery import world.gregs.voidps.engine.entity.World -import world.gregs.voidps.engine.event.Context import world.gregs.voidps.engine.entity.character.player.Player +import world.gregs.voidps.engine.entity.character.player.name import world.gregs.voidps.engine.entity.character.player.skill.Skill import world.gregs.voidps.engine.entity.character.player.skill.exp.exp import world.gregs.voidps.engine.entity.character.player.skill.level.Level.has import world.gregs.voidps.engine.entity.item.Item +import world.gregs.voidps.engine.event.Context 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.engine.inv.transact.TransactionError +import world.gregs.voidps.engine.inv.transact.operation.RemoveItem.remove +import world.gregs.voidps.engine.inv.transact.operation.ReplaceItem.replace import world.gregs.voidps.engine.queue.weakQueue -import content.skill.slayer.unlocked -import content.entity.player.dialogue.type.intEntry -import kotlin.math.min val moulds = listOf("ring", "necklace", "amulet_unstrung", "bracelet") val gems = listOf("gold", "sapphire", "emerald", "ruby", "diamond", "dragonstone", "onyx", "enchanted_gem") +val logger = InlineLogger() + val Item.jewellery: Jewellery? get() = def.getOrNull("jewellery") @@ -39,11 +43,11 @@ interfaceRefresh("make_mould*") { player -> for (type in moulds) { val showText = !player.inventory.contains("${type}_mould") player.interfaces.sendVisibility(id, "${type}_text", showText) - for (i in gems.indices) { + for (gem in gems) { if (showText) { - player.interfaces.sendVisibility(id, "make_${type}_options_$i", false) + player.interfaces.sendVisibility(id, "make_${type}_option_$gem", false) } else { - var item = Item("${if (player.inventory.contains("gold_bar") && (i == 0 || player.inventory.contains(gems[i]))) gems[i] else "blank"}_$type") + var item = Item("${if (player.inventory.contains("gold_bar") && (gem == "gold" || player.inventory.contains(gem))) gem else "blank"}_$type") if (item.id == "enchanted_gem_ring" && player.unlocked("ring_bling")) { item = Item("ring_of_slaying_8") } @@ -51,8 +55,8 @@ interfaceRefresh("make_mould*") { player -> if (jewellery == null || !player.has(Skill.Crafting, jewellery.level)) { item = Item("blank_$type") } - player.interfaces.sendVisibility(id, "make_${type}_options_$i", !item.id.startsWith("blank")) - player.interfaces.sendItem(id, "make_${type}_$i", item) + player.interfaces.sendVisibility(id, "make_${type}_option_$gem", !item.id.startsWith("blank")) + player.interfaces.sendItem(id, "make_${type}_$gem", item) } } } @@ -74,16 +78,12 @@ interfaceClose("make_mould*") { player -> } fun Context.make(component: String, amount: Int) { - val type = component.split("options_").first().removePrefix("make_").removeSuffix("_") - val index = component.split("_").last().toInt() - val gem = gems[index] + val split = component.removePrefix("make_").split("_option_") + val type = split.first() + val gem = split.last() val item = Item(if (gem == "enchanted_gem" && type == "ring") "ring_of_slaying_8" else "${gem}_$type") - val goldBars = player.inventory.count("gold_bar") - val gems = if (gem == "gold") goldBars else player.inventory.count(gem) - val current = min(goldBars, gems) - val actualAmount = if (current < amount) current else amount player.closeMenu() - player.make(item, gem, actualAmount) + player.make(item, gem, amount) } fun Player.make(item: Item, gem: String, amount: Int) { @@ -91,21 +91,31 @@ fun Player.make(item: Item, gem: String, amount: Int) { return } val data = item.jewellery ?: return - if (!has(Skill.Crafting, data.level)) { + if (!has(Skill.Crafting, data.level, message = true)) { return } if (!inventory.contains("gold_bar")) { message("You need some gold bars in order to make a ${item.id.toLowerSpaceCase()}.") return } + if (gem != "gold" && !inventory.contains(gem)) { + message("You need some ${gem.toLowerSpaceCase()} in order to make a ${item.id.toLowerSpaceCase()}.") + return + } anim("cook_range") weakQueue("make_jewllery", 3) { - if (gem != "gold" && !inventory.remove(gem)) { - message("You need some ${gem.toLowerSpaceCase()} in order to make a ${item.id.toLowerSpaceCase()}.") - return@weakQueue + inventory.transaction { + if (gem != "gold") { + remove(gem) + } + replace("gold_bar", item.id) + } + when (inventory.transaction.error) { + TransactionError.None -> { + exp(Skill.Crafting, data.xp) + make(item, gem, amount - 1) + } + else -> logger.warn { "Error crafting jewellery ${inventory.transaction.error} ${player.name} $item $gem $amount ${player.inventory.items.toList()}" } } - inventory.replace("gold_bar", item.id) - exp(Skill.Crafting, data.xp) - make(item, gem, amount - 1) } } \ No newline at end of file diff --git a/game/src/main/kotlin/content/skill/crafting/Pottery.kts b/game/src/main/kotlin/content/skill/crafting/Pottery.kts index bd6ce620e7..7fdbbca130 100644 --- a/game/src/main/kotlin/content/skill/crafting/Pottery.kts +++ b/game/src/main/kotlin/content/skill/crafting/Pottery.kts @@ -18,9 +18,6 @@ import world.gregs.voidps.engine.queue.weakQueue import content.entity.player.dialogue.type.makeAmount import content.entity.sound.playSound -val Item.pottery: Pottery - get() = def["pottery"] - itemOnObjectOperate("soft_clay", "potters_wheel*", arrive = false) { make("spinning", item) } @@ -37,7 +34,7 @@ objectOperate("Fire", "pottery_oven*", arrive = false) { } suspend fun TargetInteraction.make(animation: String, item: Item) { - val pottery = item.pottery.map + val pottery = item.def.getOrNull("pottery")?.map ?: return val (id, amount) = makeAmount( items = pottery.keys.toList(), type = "Make", diff --git a/game/src/main/kotlin/content/skill/crafting/Weaving.kts b/game/src/main/kotlin/content/skill/crafting/Weaving.kts index edbf0c53d4..8dceab5430 100644 --- a/game/src/main/kotlin/content/skill/crafting/Weaving.kts +++ b/game/src/main/kotlin/content/skill/crafting/Weaving.kts @@ -74,7 +74,7 @@ fun Player.weave(obj: GameObject, item: Item, amount: Int) { val current = inventory.count(item.id) if (current < data.amount) { val name = data.to.toLowerSpaceCase() - message("You need ${data.amount} ${plural(item)} in order to make ${name.an()} $name.") + message("You need ${data.amount} ${plural(item)} in order to make${name.an()} $name.") return } face(obj) @@ -90,7 +90,7 @@ fun Player.weave(obj: GameObject, item: Item, amount: Int) { when (inventory.transaction.error) { is TransactionError.Full, is TransactionError.Deficient -> { val name = data.to.toLowerSpaceCase() - message("You need ${data.amount} ${plural(item)} in order to make ${name.an()} $name.") + message("You need ${data.amount} ${plural(item)} in order to make${name.an()} $name.") return@weakQueue } else -> {} diff --git a/game/src/main/kotlin/content/skill/firemaking/Light.kt b/game/src/main/kotlin/content/skill/firemaking/Light.kt new file mode 100644 index 0000000000..f4263a32b4 --- /dev/null +++ b/game/src/main/kotlin/content/skill/firemaking/Light.kt @@ -0,0 +1,17 @@ +package content.skill.firemaking + +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.network.login.protocol.visual.update.player.EquipSlot + +object Light { + fun hasLightSource(player: Player): Boolean { + if (player.inventory.items.any { it.id.endsWith("lantern_lit") || it.id.endsWith("candle_lit") || it.id == "firemaking_cape_t" || it.id == "firemaking_cape" }) { + return true + } + + val cape = player.equipped(EquipSlot.Cape).id + return cape == "firemaking_cape" || cape == "firemaking_cape_t" + } +} \ No newline at end of file diff --git a/game/src/main/kotlin/content/skill/firemaking/LightSource.kts b/game/src/main/kotlin/content/skill/firemaking/LightSource.kts index 9a633b2f92..7343fbddbb 100644 --- a/game/src/main/kotlin/content/skill/firemaking/LightSource.kts +++ b/game/src/main/kotlin/content/skill/firemaking/LightSource.kts @@ -41,10 +41,10 @@ itemOnItems(arrayOf("tinderbox*"), acceptedUnlitSource) { } inventoryItem("Extinguish") { - val toExtinguish: LightSources = item.def.getOrNull("light_source") ?: return@inventoryItem + val source: LightSources = item.def.getOrNull("light_source") ?: return@inventoryItem player.inventory.transaction { - replace(item.id, toExtinguish.onceExtinguish) + replace(item.id, source.onceExtinguish) } player.message("You extinguish the flame.", ChatType.Game) diff --git a/game/src/main/kotlin/content/skill/magic/book/lunar/Vengeance.kts b/game/src/main/kotlin/content/skill/magic/book/lunar/Vengeance.kts index a6851b633c..f926093068 100644 --- a/game/src/main/kotlin/content/skill/magic/book/lunar/Vengeance.kts +++ b/game/src/main/kotlin/content/skill/magic/book/lunar/Vengeance.kts @@ -9,7 +9,7 @@ import world.gregs.voidps.engine.data.definition.SpellDefinitions import world.gregs.voidps.engine.entity.character.player.skill.Skill import world.gregs.voidps.engine.inject import world.gregs.voidps.engine.timer.epochSeconds -import content.entity.combat.hit.combatHit +import content.entity.combat.hit.combatDamage import content.entity.combat.hit.hit import content.skill.magic.spell.removeSpellItems @@ -36,9 +36,9 @@ interfaceOption("Cast", "vengeance", "lunar_spellbook") { player.start("vengeance_delay", definition["delay_seconds"], epochSeconds()) } -combatHit { player -> +combatDamage { player -> if (!player.contains("vengeance") || type == "damage" || damage < 4) { - return@combatHit + return@combatDamage } player.say("Taste vengeance!") player.hit(target = source, type = "damage", delay = 0, damage = (damage * 0.75).toInt()) diff --git a/game/src/main/kotlin/content/skill/magic/jewellery/GamesNecklace.kts b/game/src/main/kotlin/content/skill/magic/jewellery/GamesNecklace.kts index c3b9924182..715380bc9f 100644 --- a/game/src/main/kotlin/content/skill/magic/jewellery/GamesNecklace.kts +++ b/game/src/main/kotlin/content/skill/magic/jewellery/GamesNecklace.kts @@ -2,7 +2,7 @@ package content.skill.magic.jewellery import world.gregs.voidps.engine.data.definition.AreaDefinitions import world.gregs.voidps.engine.inject -import content.quest.questComplete +import content.quest.questCompleted import content.entity.player.dialogue.type.choice import content.entity.player.dialogue.type.statement import content.entity.player.inv.inventoryItem @@ -29,10 +29,10 @@ inventoryItem("Rub", "games_necklace_#", "inventory") { option("Wilderness Volcano.") { jewelleryTeleport(player, inventory, slot, wildernessVolcano) } - option("Burgh De Rott.", { player.questComplete("darkness_of_hallowvale") }) { + option("Burgh De Rott.", { player.questCompleted("darkness_of_hallowvale") }) { jewelleryTeleport(player, inventory, slot, burghDeRott) } - option("Nowhere.", { !player.questComplete("darkness_of_hallowvale") }) + option("Nowhere.", { !player.questCompleted("darkness_of_hallowvale") }) } } @@ -43,7 +43,7 @@ inventoryItem("*", "games_necklace_#", "worn_equipment") { "Clan Wars" -> clanWars "Wilderness Volcano" -> wildernessVolcano "Burgh De Rott" -> { - if (!player.questComplete("darkness_of_hallowvale")) { + if (!player.questCompleted("darkness_of_hallowvale")) { statement("You need to have completed The Darkness of Hallowvale quest to teleport to this location.") return@inventoryItem } diff --git a/game/src/main/kotlin/content/skill/magic/spell/Spell.kt b/game/src/main/kotlin/content/skill/magic/spell/Spell.kt index d29e3206d4..be2805c63c 100644 --- a/game/src/main/kotlin/content/skill/magic/spell/Spell.kt +++ b/game/src/main/kotlin/content/skill/magic/spell/Spell.kt @@ -1,31 +1,17 @@ package content.skill.magic.spell -import world.gregs.voidps.cache.definition.data.InterfaceComponentDefinition +import content.entity.player.equip.Equipment import world.gregs.voidps.engine.client.message import world.gregs.voidps.engine.client.variable.hasClock import world.gregs.voidps.engine.data.config.SpellDefinition -import world.gregs.voidps.engine.data.definition.InterfaceDefinitions -import world.gregs.voidps.engine.data.definition.ItemDefinitions import world.gregs.voidps.engine.data.definition.SpellDefinitions -import world.gregs.voidps.engine.entity.World import world.gregs.voidps.engine.entity.character.Character 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.level.Level.has import world.gregs.voidps.engine.entity.item.Item import world.gregs.voidps.engine.get -import world.gregs.voidps.engine.inv.* -import world.gregs.voidps.engine.inv.transact.Transaction -import world.gregs.voidps.engine.inv.transact.TransactionError -import world.gregs.voidps.engine.inv.transact.operation.RemoveItem.remove -import world.gregs.voidps.network.login.protocol.visual.update.player.EquipSlot -import world.gregs.voidps.type.random -import content.entity.player.equip.Equipment -import content.skill.magic.spell.Spell.removeItems import kotlin.math.absoluteValue -import kotlin.math.max import kotlin.math.roundToInt object Spell { @@ -75,206 +61,6 @@ object Spell { return damage } - fun Transaction.removeItems(player: Player, spell: String, message: Boolean = true) { - val component = get().getComponent(player.spellBook, spell) - if (component == null || !player.has(Skill.Magic, component.magicLevel, message = message)) { - error = TransactionError.Deficient(0) - return - } - val required = component.spellRequiredItems() - if (required == null) { - error = TransactionError.Deficient(0) - return - } - checkInfiniteStaff(player, required, "air") - checkInfiniteStaff(player, required, "water") - checkInfiniteStaff(player, required, "earth") - checkInfiniteStaff(player, required, "fire") - - dungeoneeringMagicBoxes(player, required, spell) - checkMinigame(player, required) - if (World.members) { - removeCombo(required, "mist_rune", "air_rune", "water_rune") - removeCombo(required, "dust_rune", "air_rune", "earth_rune") - removeCombo(required, "mud_rune", "water_rune", "earth_rune") - removeCombo(required, "smoke_rune", "air_rune", "fire_rune") - removeCombo(required, "steam_rune", "water_rune", "fire_rune") - removeCombo(required, "lava_rune", "earth_rune", "fire_rune") - } - dungeoneeringStaffCharges(required, player, message) - checkStaves(player, required) - // Regular runes - required.keys.removeIf { key -> - if (!key.endsWith("_rune")) { - false - } else { - remove(key, required.getValue(key)) - !failed - } - } - if (required.isNotEmpty()) { - error = TransactionError.Deficient(required.values.first()) - if (message) { - player.message("You do not have the required items to cast this spell.") - } - } - } - - private fun Transaction.dungeoneeringStaffCharges(required: MutableMap, player: Player, message: Boolean) { - if (required.containsKey("nature_rune") && player.equipped(EquipSlot.Weapon).id == "nature_staff") { - val charges = player.equipment.charges(player, EquipSlot.Weapon.index) - val amount = required.dec("nature_rune", charges) - if (random.nextInt(10) == 0 && message) { - player.message("Your staff magically pays for the cost of the nature rune.", ChatType.Filter) - } else if (player.equipment.discharge(player, EquipSlot.Weapon.index, amount)) { - state.onRevert { player.equipment.charge(player, EquipSlot.Weapon.index, amount) } - } - } else if (required.containsKey("law_rune") && player.equipped(EquipSlot.Weapon).id == "law_staff") { - val charges = player.equipment.charges(player, EquipSlot.Weapon.index) - val amount = required.dec("law_rune", charges) - if (random.nextInt(10) == 0 && message) { - player.message("Your staff magically pays for the cost of the law rune.", ChatType.Filter) - } else if (player.equipment.discharge(player, EquipSlot.Weapon.index, amount = amount)) { - state.onRevert { player.equipment.charge(player, EquipSlot.Weapon.index, amount = amount) } - } - } - } - - private fun MutableMap.dec(key: String, value: Int): Int { - val count = this[key] ?: return 0 - val max = value.coerceAtMost(count) - val reduced = count - max - if (reduced <= 0) { - this.remove(key) - } else { - this[key] = reduced - } - return max - } - - private fun Transaction.dungeoneeringMagicBoxes(player: Player, required: MutableMap, spell: String) { - if (removeBoxCharges(player, spell, "magical_blastbox", "_bolt")) { - required.remove("air_rune") - required.remove("chaos_rune") - } else if (removeBoxCharges(player, spell, "magical_blastbox", "_blast")) { - required.remove("air_rune") - required.remove("death_rune") - } else if (removeBoxCharges(player, spell, "celestial_surgebox", "_wave")) { - required.remove("air_rune") - required.remove("blood_rune") - } else if (removeBoxCharges(player, spell, "celestial_surgebox", "_surge")) { - required.remove("air_rune") - required.remove("death_rune") - required.remove("blood_rune") - } - } - - private fun Transaction.removeBoxCharges(player: Player, spell: String, box: String, suffix: String): Boolean { - if (spell.endsWith(suffix) && player.equipped(EquipSlot.Shield).id.startsWith(box)) { - if (player.equipment.discharge(player, EquipSlot.Shield.index)) { - state.onRevert { player.equipment.charge(player, EquipSlot.Shield.index) } - return true - } - } - return false - } - - private fun checkInfiniteStaff(player: Player, required: MutableMap, element: String) { - if (required.containsKey("${element}_rune") && player.equipped(EquipSlot.Weapon).def.contains("infinite_${element}_runes")) { - required.remove("${element}_rune") - } - } - - private val elementalRunes = listOf("air_rune", "water_rune", "earth_rune", "fire_rune") - private val catalyticRunes = listOf("body_rune", "mind_rune", "cosmic_rune", "chaos_rune", "nature_rune", "death_rune", "law_rune", "soul_rune", "blood_rune", "astral_rune") - - private fun Transaction.checkMinigame(player: Player, required: MutableMap) { - val type = player["minigame_type", "none"] - if (type != "stealing_creation" && type != "fist_of_guthix" && type != "barbarian_assault") { - return - } - val elemental = inventory.count("elemental_rune") - val catalyst = inventory.count("catalytic_rune") - var count = 0 - for (rune in elementalRunes) { - if (required.containsKey(rune) && count < elemental) { - count += required.dec(rune, elemental) - } - } - remove("elemental_rune", count) - count = 0 - for (rune in catalyticRunes) { - if (!World.members && rune == "soul_rune") { - break - } - if (required.containsKey(rune) && count < catalyst) { - count += required.dec(rune, catalyst) - } - } - remove("catalytic_rune", count) - } - - private fun checkStaves(player: Player, required: MutableMap) { - val weapon = player.equipped(EquipSlot.Weapon).id - when { - weapon == "guthix_staff" || weapon == "void_knight_mace" -> required.remove("guthix_staff_dummy") - weapon == "slayers_staff" || weapon.startsWith("staff_of_light") -> required.remove("slayers_staff") - weapon.startsWith("zuriels_staff") -> required.remove("zuriels_staff") - weapon == "ibans_staff" -> required.remove("ibans_staff") - weapon == "saradomin_staff" -> required.remove("saradomin_staff") - weapon == "zamorak_staff" -> required.remove("zamorak_staff") - } - } - - private fun Transaction.removeCombo(required: MutableMap, combo: String, element1: String, element2: String) { - if (!inventory.contains(combo)) { - return - } - if (!required.containsKey(element1) && !required.containsKey(element2)) { - return - } - val count = inventory.count(combo) - val removed = max(required.dec(element1, count), required.dec(element2, count)) - if (removed > 0) { - remove(combo, removed) - } - } - - private val InterfaceComponentDefinition.magicLevel: Int - get() = information?.getOrNull(5) as? Int ?: 0 - - private fun InterfaceComponentDefinition.spellRequiredItems(): MutableMap? { - val array = information ?: return null - val map = mutableMapOf() - val definitions: ItemDefinitions = get() - for (i in 8..14 step 2) { - val id = array[i] as Int - val amount = array[i + 1] as Int - if (id == -1 || amount <= 0) { - break - } - val item = definitions.get(id) - if (item.members && !World.members) { - return null - } - map[item.stringId] = amount - } - return map - } -} - - -fun Player.hasSpellItems(spell: String, message: Boolean = true): Boolean { - val transaction = inventory.transaction - transaction.start() - transaction.removeItems(this, spell, message) - val success = !transaction.failed - transaction.revert() - return success -} - -fun Player.removeSpellItems(spell: String) = inventory.transaction { - removeItems(this@removeSpellItems, spell) } var Character.spell: String diff --git a/game/src/main/kotlin/content/skill/magic/spell/SpellRunes.kt b/game/src/main/kotlin/content/skill/magic/spell/SpellRunes.kt new file mode 100644 index 0000000000..d6d206a87f --- /dev/null +++ b/game/src/main/kotlin/content/skill/magic/spell/SpellRunes.kt @@ -0,0 +1,225 @@ +package content.skill.magic.spell + +import content.skill.magic.spell.SpellRunes.removeItems +import world.gregs.voidps.cache.definition.data.InterfaceComponentDefinition +import world.gregs.voidps.engine.client.message +import world.gregs.voidps.engine.data.definition.InterfaceDefinitions +import world.gregs.voidps.engine.data.definition.ItemDefinitions +import world.gregs.voidps.engine.entity.World +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.level.Level.has +import world.gregs.voidps.engine.get +import world.gregs.voidps.engine.inv.* +import world.gregs.voidps.engine.inv.transact.Transaction +import world.gregs.voidps.engine.inv.transact.TransactionError +import world.gregs.voidps.engine.inv.transact.operation.RemoveItem.remove +import world.gregs.voidps.network.login.protocol.visual.update.player.EquipSlot +import world.gregs.voidps.type.random +import kotlin.math.max + +object SpellRunes { + + fun Transaction.removeItems(player: Player, spell: String, message: Boolean = true) { + val component = get().getComponent(player.spellBook, spell) + if (component == null || !player.has(Skill.Magic, component.magicLevel, message = message)) { + error = TransactionError.Deficient(0) + return + } + val required = component.spellRequiredItems() + if (required == null) { + error = TransactionError.Deficient(0) + return + } + checkInfiniteStaff(player, required, "air") + checkInfiniteStaff(player, required, "water") + checkInfiniteStaff(player, required, "earth") + checkInfiniteStaff(player, required, "fire") + + dungeoneeringMagicBoxes(player, required, spell) + checkMinigame(player, required) + if (World.members) { + removeCombo(required, "mist_rune", "air_rune", "water_rune") + removeCombo(required, "dust_rune", "air_rune", "earth_rune") + removeCombo(required, "mud_rune", "water_rune", "earth_rune") + removeCombo(required, "smoke_rune", "air_rune", "fire_rune") + removeCombo(required, "steam_rune", "water_rune", "fire_rune") + removeCombo(required, "lava_rune", "earth_rune", "fire_rune") + } + dungeoneeringStaffCharges(required, player, message) + checkStaves(player, required) + // Regular runes + required.keys.removeIf { key -> + if (!key.endsWith("_rune")) { + false + } else { + remove(key, required.getValue(key)) + !failed + } + } + if (required.isNotEmpty()) { + error = TransactionError.Deficient(required.values.first()) + if (message) { + player.message("You do not have the required items to cast this spell.") + } + } + } + + private fun Transaction.dungeoneeringStaffCharges(required: MutableMap, player: Player, message: Boolean) { + if (required.containsKey("nature_rune") && player.equipped(EquipSlot.Weapon).id == "nature_staff") { + val charges = player.equipment.charges(player, EquipSlot.Weapon.index) + val amount = required.dec("nature_rune", charges) + if (random.nextInt(10) == 0 && message) { + player.message("Your staff magically pays for the cost of the nature rune.", ChatType.Filter) + } else if (player.equipment.discharge(player, EquipSlot.Weapon.index, amount)) { + state.onRevert { player.equipment.charge(player, EquipSlot.Weapon.index, amount) } + } + } else if (required.containsKey("law_rune") && player.equipped(EquipSlot.Weapon).id == "law_staff") { + val charges = player.equipment.charges(player, EquipSlot.Weapon.index) + val amount = required.dec("law_rune", charges) + if (random.nextInt(10) == 0 && message) { + player.message("Your staff magically pays for the cost of the law rune.", ChatType.Filter) + } else if (player.equipment.discharge(player, EquipSlot.Weapon.index, amount = amount)) { + state.onRevert { player.equipment.charge(player, EquipSlot.Weapon.index, amount = amount) } + } + } + } + + private fun MutableMap.dec(key: String, value: Int): Int { + val count = this[key] ?: return 0 + val max = value.coerceAtMost(count) + val reduced = count - max + if (reduced <= 0) { + this.remove(key) + } else { + this[key] = reduced + } + return max + } + + private fun Transaction.dungeoneeringMagicBoxes(player: Player, required: MutableMap, spell: String) { + if (removeBoxCharges(player, spell, "magical_blastbox", "_bolt")) { + required.remove("air_rune") + required.remove("chaos_rune") + } else if (removeBoxCharges(player, spell, "magical_blastbox", "_blast")) { + required.remove("air_rune") + required.remove("death_rune") + } else if (removeBoxCharges(player, spell, "celestial_surgebox", "_wave")) { + required.remove("air_rune") + required.remove("blood_rune") + } else if (removeBoxCharges(player, spell, "celestial_surgebox", "_surge")) { + required.remove("air_rune") + required.remove("death_rune") + required.remove("blood_rune") + } + } + + private fun Transaction.removeBoxCharges(player: Player, spell: String, box: String, suffix: String): Boolean { + if (spell.endsWith(suffix) && player.equipped(EquipSlot.Shield).id.startsWith(box)) { + if (player.equipment.discharge(player, EquipSlot.Shield.index)) { + state.onRevert { player.equipment.charge(player, EquipSlot.Shield.index) } + return true + } + } + return false + } + + private fun checkInfiniteStaff(player: Player, required: MutableMap, element: String) { + if (required.containsKey("${element}_rune") && player.equipped(EquipSlot.Weapon).def.contains("infinite_${element}_runes")) { + required.remove("${element}_rune") + } + } + + private val elementalRunes = listOf("air_rune", "water_rune", "earth_rune", "fire_rune") + private val catalyticRunes = listOf("body_rune", "mind_rune", "cosmic_rune", "chaos_rune", "nature_rune", "death_rune", "law_rune", "soul_rune", "blood_rune", "astral_rune") + + private fun Transaction.checkMinigame(player: Player, required: MutableMap) { + val type = player["minigame_type", "none"] + if (type != "stealing_creation" && type != "fist_of_guthix" && type != "barbarian_assault") { + return + } + val elemental = inventory.count("elemental_rune") + val catalyst = inventory.count("catalytic_rune") + var count = 0 + for (rune in elementalRunes) { + if (required.containsKey(rune) && count < elemental) { + count += required.dec(rune, elemental) + } + } + remove("elemental_rune", count) + count = 0 + for (rune in catalyticRunes) { + if (!World.members && rune == "soul_rune") { + break + } + if (required.containsKey(rune) && count < catalyst) { + count += required.dec(rune, catalyst) + } + } + remove("catalytic_rune", count) + } + + private fun checkStaves(player: Player, required: MutableMap) { + val weapon = player.equipped(EquipSlot.Weapon).id + when { + weapon == "guthix_staff" || weapon == "void_knight_mace" -> required.remove("guthix_staff_dummy") + weapon == "slayers_staff" || weapon.startsWith("staff_of_light") -> required.remove("slayers_staff") + weapon.startsWith("zuriels_staff") -> required.remove("zuriels_staff") + weapon == "ibans_staff" -> required.remove("ibans_staff") + weapon == "saradomin_staff" -> required.remove("saradomin_staff") + weapon == "zamorak_staff" -> required.remove("zamorak_staff") + } + } + + private fun Transaction.removeCombo(required: MutableMap, combo: String, element1: String, element2: String) { + if (!inventory.contains(combo)) { + return + } + if (!required.containsKey(element1) && !required.containsKey(element2)) { + return + } + val count = inventory.count(combo) + val removed = max(required.dec(element1, count), required.dec(element2, count)) + if (removed > 0) { + remove(combo, removed) + } + } + + private val InterfaceComponentDefinition.magicLevel: Int + get() = information?.getOrNull(5) as? Int ?: 0 + + private fun InterfaceComponentDefinition.spellRequiredItems(): MutableMap? { + val array = information ?: return null + val map = mutableMapOf() + val definitions: ItemDefinitions = get() + for (i in 8..14 step 2) { + val id = array[i] as Int + val amount = array[i + 1] as Int + if (id == -1 || amount <= 0) { + break + } + val item = definitions.get(id) + if (item.members && !World.members) { + return null + } + map[item.stringId] = amount + } + return map + } +} + + +fun Player.hasSpellItems(spell: String, message: Boolean = true): Boolean { + val transaction = inventory.transaction + transaction.start() + transaction.removeItems(this, spell, message) + val success = !transaction.failed + transaction.revert() + return success +} + +fun Player.removeSpellItems(spell: String) = inventory.transaction { + removeItems(this@removeSpellItems, spell) +} \ No newline at end of file diff --git a/game/src/main/kotlin/content/skill/magic/spell/Spells.kts b/game/src/main/kotlin/content/skill/magic/spell/Spells.kts index 72eec9cdb2..74fdaf20bd 100644 --- a/game/src/main/kotlin/content/skill/magic/spell/Spells.kts +++ b/game/src/main/kotlin/content/skill/magic/spell/Spells.kts @@ -1,16 +1,16 @@ package content.skill.magic.spell import world.gregs.voidps.type.random -import content.entity.combat.hit.characterCombatHit +import content.entity.combat.hit.characterCombatDamage import content.entity.combat.hit.combatAttack import content.entity.combat.hit.directHit import content.area.wilderness.inMultiCombat import content.skill.melee.weapon.multiTargets import kotlin.random.nextInt -characterCombatHit { character -> +characterCombatDamage { character -> if (spell.isNotBlank()) { - character.gfx("${spell}_hit") + character.gfx("${spell}_impact") } } diff --git a/game/src/main/kotlin/content/skill/melee/Block.kts b/game/src/main/kotlin/content/skill/melee/Block.kts index 75b3764195..55d9358c04 100644 --- a/game/src/main/kotlin/content/skill/melee/Block.kts +++ b/game/src/main/kotlin/content/skill/melee/Block.kts @@ -36,11 +36,11 @@ characterCombatAttack { character -> } else { val type: String? = target.weapon.def.getOrNull("weapon_type") val definition = if (type != null) weaponDefinitions.get(type) else null - var animation = definition?.attackTypes?.get("hit") + var animation = definition?.attackTypes?.get("defend") if (animation == null) { val id = target.weapon.def["weapon_style", -1] val style = styleDefinitions.get(id) - animation = if (id != -1 && animationDefinitions.contains("${style.stringId}_hit")) "${style.stringId}_hit" else "human_hit" + animation = if (id != -1 && animationDefinitions.contains("${style.stringId}_defend")) "${style.stringId}_defend" else "human_defend" } target.anim(animation, delay) } @@ -51,18 +51,18 @@ characterCombatAttack { character -> } fun hitAnimation(npc: NPC): String { - var animation = "${npc.id}_hit" + var animation = "${npc.id}_defend" if (animationDefinitions.contains(animation)) { return animation } - if (npc.def.contains("hit_anim")) { - animation = npc.def["hit_anim", ""] + if (npc.def.contains("defend_anim")) { + animation = npc.def["defend_anim", ""] if (animationDefinitions.contains(animation)) { return animation } } if (npc.race.isNotEmpty()) { - animation = "${npc.race}_hit" + animation = "${npc.race}_defend" if (animationDefinitions.contains(animation)) { return animation } @@ -73,18 +73,18 @@ fun hitAnimation(npc: NPC): String { fun calculateHitSound(target: Character): String { if (target is NPC) { var sound: String - if (target.def.contains("hit_sound")) { - sound = target.def["hit_sound"] + if (target.def.contains("defend_sound")) { + sound = target.def["defend_sound"] if (soundDefinitions.contains(sound)) { return sound } } - sound = "${target.id}_hit" + sound = "${target.id}_defend" if (soundDefinitions.contains(sound)) { return sound } if (target.race.isNotEmpty()) { - sound = "${target.race}_hit" + sound = "${target.race}_defend" if (soundDefinitions.contains(sound)) { return sound } @@ -94,10 +94,10 @@ fun calculateHitSound(target: Character): String { if (target is Player) { return if (target.male) { - "male_hit_${random.nextInt(0, 3)}" + "male_defend_${random.nextInt(0, 3)}" } else { - "female_hit_${random.nextInt(0, 1)}" + "female_defend_${random.nextInt(0, 1)}" } } - return "human_hit" + return "human_defend" } \ No newline at end of file diff --git a/game/src/main/kotlin/content/skill/melee/armour/Degradation.kts b/game/src/main/kotlin/content/skill/melee/armour/Degradation.kts index ca9946aeb6..a13be0b753 100644 --- a/game/src/main/kotlin/content/skill/melee/armour/Degradation.kts +++ b/game/src/main/kotlin/content/skill/melee/armour/Degradation.kts @@ -10,9 +10,9 @@ import world.gregs.voidps.engine.inv.equipment import world.gregs.voidps.engine.inv.itemChange import world.gregs.voidps.network.login.protocol.visual.update.player.EquipSlot import content.entity.combat.hit.combatAttack -import content.entity.combat.hit.combatHit +import content.entity.combat.hit.combatDamage -combatHit { player -> +combatDamage { player -> degrade(player) } diff --git a/game/src/main/kotlin/content/skill/melee/armour/RingOfRecoil.kts b/game/src/main/kotlin/content/skill/melee/armour/RingOfRecoil.kts index 9ccbcf354c..2413b798a0 100644 --- a/game/src/main/kotlin/content/skill/melee/armour/RingOfRecoil.kts +++ b/game/src/main/kotlin/content/skill/melee/armour/RingOfRecoil.kts @@ -7,19 +7,19 @@ import world.gregs.voidps.engine.inv.charges import world.gregs.voidps.engine.inv.discharge import world.gregs.voidps.engine.inv.equipment import world.gregs.voidps.network.login.protocol.visual.update.player.EquipSlot -import content.entity.combat.hit.combatHit +import content.entity.combat.hit.combatDamage import content.entity.combat.hit.directHit import content.entity.player.inv.inventoryItem -combatHit { player -> +combatDamage { player -> if (source == player || type == "deflect" || type == "poison" || type == "disease" || type == "healed" || damage < 1) { - return@combatHit + return@combatDamage } if (player.equipped(EquipSlot.Ring).id != "ring_of_recoil") { - return@combatHit + return@combatDamage } if (source is NPC && source.def["immune_deflect", false]) { - return@combatHit + return@combatDamage } val charges = player.equipment.charges(player, EquipSlot.Ring.index) val deflect = (10 + (damage / 10)).coerceAtMost(charges) diff --git a/game/src/main/kotlin/content/skill/melee/weapon/special/AbyssalWhip.kts b/game/src/main/kotlin/content/skill/melee/weapon/special/AbyssalWhip.kts index 011c5cf50a..8470126c7d 100644 --- a/game/src/main/kotlin/content/skill/melee/weapon/special/AbyssalWhip.kts +++ b/game/src/main/kotlin/content/skill/melee/weapon/special/AbyssalWhip.kts @@ -2,12 +2,12 @@ package content.skill.melee.weapon.special import world.gregs.voidps.engine.client.message import world.gregs.voidps.engine.entity.character.player.Player -import content.entity.player.combat.special.specialAttackHit +import content.entity.player.combat.special.specialAttackDamage import content.entity.player.effect.energy.runEnergy -specialAttackHit("energy_drain") { player -> +specialAttackDamage("energy_drain") { player -> if (target !is Player) { - return@specialAttackHit + return@specialAttackDamage } val tenPercent = (target.runEnergy / 100) * 10 if (tenPercent > 0) { diff --git a/game/src/main/kotlin/content/skill/melee/weapon/special/AncientMace.kts b/game/src/main/kotlin/content/skill/melee/weapon/special/AncientMace.kts index fb11553a27..097534dfcd 100644 --- a/game/src/main/kotlin/content/skill/melee/weapon/special/AncientMace.kts +++ b/game/src/main/kotlin/content/skill/melee/weapon/special/AncientMace.kts @@ -1,9 +1,9 @@ package content.skill.melee.weapon.special import world.gregs.voidps.engine.entity.character.player.skill.Skill -import content.entity.player.combat.special.specialAttackHit +import content.entity.player.combat.special.specialAttackDamage -specialAttackHit("favour_of_the_war_god") { player -> +specialAttackDamage("favour_of_the_war_god") { player -> val drain = damage / 10 if (drain > 0) { target.levels.drain(Skill.Prayer, drain) diff --git a/game/src/main/kotlin/content/skill/melee/weapon/special/BandosGodsword.kts b/game/src/main/kotlin/content/skill/melee/weapon/special/BandosGodsword.kts index 9eb27b917d..2c0ed5e3f6 100644 --- a/game/src/main/kotlin/content/skill/melee/weapon/special/BandosGodsword.kts +++ b/game/src/main/kotlin/content/skill/melee/weapon/special/BandosGodsword.kts @@ -2,8 +2,8 @@ package content.skill.melee.weapon.special import world.gregs.voidps.engine.entity.character.player.skill.Skill import content.skill.melee.weapon.drainByDamage -import content.entity.player.combat.special.specialAttackHit +import content.entity.player.combat.special.specialAttackDamage -specialAttackHit("warstrike") { +specialAttackDamage("warstrike") { drainByDamage(target, damage, Skill.Defence, Skill.Strength, Skill.Prayer, Skill.Attack, Skill.Magic, Skill.Ranged) } diff --git a/game/src/main/kotlin/content/skill/melee/weapon/special/BoneDagger.kts b/game/src/main/kotlin/content/skill/melee/weapon/special/BoneDagger.kts index 1f0ae4060f..8e0f003825 100644 --- a/game/src/main/kotlin/content/skill/melee/weapon/special/BoneDagger.kts +++ b/game/src/main/kotlin/content/skill/melee/weapon/special/BoneDagger.kts @@ -2,8 +2,8 @@ package content.skill.melee.weapon.special import world.gregs.voidps.engine.entity.character.player.skill.Skill import content.skill.melee.weapon.drainByDamage -import content.entity.player.combat.special.specialAttackHit +import content.entity.player.combat.special.specialAttackDamage -specialAttackHit("backstab") { +specialAttackDamage("backstab") { drainByDamage(target, damage, Skill.Defence) } \ No newline at end of file diff --git a/game/src/main/kotlin/content/skill/melee/weapon/special/Darklight.kts b/game/src/main/kotlin/content/skill/melee/weapon/special/Darklight.kts index dcb36553c5..0937a5b705 100644 --- a/game/src/main/kotlin/content/skill/melee/weapon/special/Darklight.kts +++ b/game/src/main/kotlin/content/skill/melee/weapon/special/Darklight.kts @@ -2,9 +2,9 @@ package content.skill.melee.weapon.special import world.gregs.voidps.engine.entity.character.player.skill.Skill import content.entity.combat.Target -import content.entity.player.combat.special.specialAttackHit +import content.entity.player.combat.special.specialAttackDamage -specialAttackHit("weaken") { +specialAttackDamage("weaken") { val amount = if (Target.isDemon(target)) 0.10 else 0.05 target.levels.drain(Skill.Attack, multiplier = amount) target.levels.drain(Skill.Strength, multiplier = amount) diff --git a/game/src/main/kotlin/content/skill/melee/weapon/special/Dragon2hSword.kts b/game/src/main/kotlin/content/skill/melee/weapon/special/Dragon2hSword.kts index 24f7eb0ea6..d0a6fe4969 100644 --- a/game/src/main/kotlin/content/skill/melee/weapon/special/Dragon2hSword.kts +++ b/game/src/main/kotlin/content/skill/melee/weapon/special/Dragon2hSword.kts @@ -9,14 +9,14 @@ import world.gregs.voidps.type.Direction import content.entity.combat.Target import content.entity.combat.hit.hit import content.area.wilderness.inMultiCombat -import content.entity.player.combat.special.specialAttackHit +import content.entity.player.combat.special.specialAttackDamage val players: Players by inject() val npcs: NPCs by inject() -specialAttackHit("powerstab") { player -> +specialAttackDamage("powerstab") { player -> if (!player.inMultiCombat) { - return@specialAttackHit + return@specialAttackDamage } val characters: CharacterList<*> = if (target is Player) players else npcs var remaining = if (target is Player) 2 else 14 @@ -28,7 +28,7 @@ specialAttackHit("powerstab") { player -> } player.hit(char) if (--remaining <= 0) { - return@specialAttackHit + return@specialAttackDamage } } } diff --git a/game/src/main/kotlin/content/skill/melee/weapon/special/DragonDagger.kts b/game/src/main/kotlin/content/skill/melee/weapon/special/DragonDagger.kts index f3b3b5fd10..545dca072b 100644 --- a/game/src/main/kotlin/content/skill/melee/weapon/special/DragonDagger.kts +++ b/game/src/main/kotlin/content/skill/melee/weapon/special/DragonDagger.kts @@ -1,8 +1,8 @@ package content.skill.melee.weapon.special import content.entity.combat.hit.hit -import content.entity.player.combat.special.specialAttackHit +import content.entity.player.combat.special.specialAttackDamage -specialAttackHit("puncture", noHit = false) { player -> +specialAttackDamage("puncture", noHit = false) { player -> player.hit(target) } \ No newline at end of file diff --git a/game/src/main/kotlin/content/skill/melee/weapon/special/DragonHatchet.kts b/game/src/main/kotlin/content/skill/melee/weapon/special/DragonHatchet.kts index f49b6b8002..1f915812bc 100644 --- a/game/src/main/kotlin/content/skill/melee/weapon/special/DragonHatchet.kts +++ b/game/src/main/kotlin/content/skill/melee/weapon/special/DragonHatchet.kts @@ -1,9 +1,9 @@ package content.skill.melee.weapon.special import world.gregs.voidps.engine.entity.character.player.skill.Skill -import content.entity.player.combat.special.specialAttackHit +import content.entity.player.combat.special.specialAttackDamage -specialAttackHit("clobber") { +specialAttackDamage("clobber") { val drain = damage / 100 if (drain > 0) { target.levels.drain(Skill.Defence, drain) diff --git a/game/src/main/kotlin/content/skill/melee/weapon/special/DragonScimitar.kts b/game/src/main/kotlin/content/skill/melee/weapon/special/DragonScimitar.kts index 4b90f64441..8732b11814 100644 --- a/game/src/main/kotlin/content/skill/melee/weapon/special/DragonScimitar.kts +++ b/game/src/main/kotlin/content/skill/melee/weapon/special/DragonScimitar.kts @@ -8,10 +8,10 @@ import world.gregs.voidps.engine.timer.toTicks import content.skill.prayer.getActivePrayerVarKey import content.skill.prayer.isCurses import content.skill.prayer.prayerStart -import content.entity.player.combat.special.specialAttackHit +import content.entity.player.combat.special.specialAttackDamage import java.util.concurrent.TimeUnit -specialAttackHit("sever") { +specialAttackDamage("sever") { target.softTimers.start(id) } diff --git a/game/src/main/kotlin/content/skill/melee/weapon/special/KorasiSword.kts b/game/src/main/kotlin/content/skill/melee/weapon/special/KorasiSword.kts index d215f348ad..b4b98e7683 100644 --- a/game/src/main/kotlin/content/skill/melee/weapon/special/KorasiSword.kts +++ b/game/src/main/kotlin/content/skill/melee/weapon/special/KorasiSword.kts @@ -10,7 +10,7 @@ import world.gregs.voidps.engine.map.spiral import world.gregs.voidps.type.random import content.entity.combat.Target import content.entity.combat.hit.Damage -import content.entity.combat.hit.characterCombatHit +import content.entity.combat.hit.characterCombatDamage import content.entity.combat.hit.hit import content.area.wilderness.inMultiCombat import content.skill.melee.weapon.weapon @@ -32,18 +32,18 @@ specialAttack("disrupt") { player -> player.hit(target, damage = hit, type = "magic", delay = 0) } -characterCombatHit("korasis_sword") { target -> +characterCombatDamage("korasis_sword") { target -> if (!special) { - return@characterCombatHit + return@characterCombatDamage } areaSound("godwars_saradomin_magic_impact", target.tile, 10) - target.gfx("disrupt_hit") + target.gfx("disrupt_impact") if (!target.inMultiCombat) { - return@characterCombatHit + return@characterCombatDamage } val chain: MutableSet = source["korasi_chain", mutableSetOf()] if (chain.size >= 3) { - return@characterCombatHit + return@characterCombatDamage } val characters = if (target is Player) players else npcs for (tile in target.tile.spiral(4)) { @@ -58,10 +58,10 @@ characterCombatHit("korasis_sword") { target -> val hit = damage / when (chain.size) { 2 -> 2 3 -> 4 - else -> return@characterCombatHit + else -> return@characterCombatDamage } source.hit(character, damage = hit, weapon = weapon, type = type, special = true) - return@characterCombatHit + return@characterCombatDamage } } } \ No newline at end of file diff --git a/game/src/main/kotlin/content/skill/melee/weapon/special/SaradominGodsword.kts b/game/src/main/kotlin/content/skill/melee/weapon/special/SaradominGodsword.kts index 9a6945ea5d..9a9440909c 100644 --- a/game/src/main/kotlin/content/skill/melee/weapon/special/SaradominGodsword.kts +++ b/game/src/main/kotlin/content/skill/melee/weapon/special/SaradominGodsword.kts @@ -1,10 +1,10 @@ package content.skill.melee.weapon.special import world.gregs.voidps.engine.entity.character.player.skill.Skill -import content.entity.player.combat.special.specialAttackHit +import content.entity.player.combat.special.specialAttackDamage import kotlin.math.max -specialAttackHit("healing_blade") { player -> +specialAttackDamage("healing_blade") { player -> player.levels.restore(Skill.Constitution, max(100, damage / 20)) player.levels.restore(Skill.Prayer, max(50, damage / 40)) } \ No newline at end of file diff --git a/game/src/main/kotlin/content/skill/melee/weapon/special/SpearShove.kts b/game/src/main/kotlin/content/skill/melee/weapon/special/SpearShove.kts index 6a259a115f..1ab6619133 100644 --- a/game/src/main/kotlin/content/skill/melee/weapon/special/SpearShove.kts +++ b/game/src/main/kotlin/content/skill/melee/weapon/special/SpearShove.kts @@ -29,7 +29,7 @@ specialAttack("shove") { player -> player.anim("${id}_special") player.gfx("${id}_special") val duration = TimeUnit.SECONDS.toTicks(3) - target.gfx("shove_hit") + target.gfx("dragon_spear_stun") target.freeze(duration) player["delay"] = duration player.hit(target, damage = -1) // Hit with no damage so target can auto-retaliate diff --git a/game/src/main/kotlin/content/skill/melee/weapon/special/StaffOfLight.kts b/game/src/main/kotlin/content/skill/melee/weapon/special/StaffOfLight.kts index 87fa69e9e0..877e772b5a 100644 --- a/game/src/main/kotlin/content/skill/melee/weapon/special/StaffOfLight.kts +++ b/game/src/main/kotlin/content/skill/melee/weapon/special/StaffOfLight.kts @@ -8,7 +8,7 @@ import world.gregs.voidps.engine.timer.timerStop import world.gregs.voidps.engine.timer.timerTick import world.gregs.voidps.engine.timer.toTicks import world.gregs.voidps.network.login.protocol.visual.update.player.EquipSlot -import content.entity.combat.hit.combatHit +import content.entity.combat.hit.combatDamage import content.entity.player.combat.special.SpecialAttack import content.entity.player.combat.special.specialAttackPrepare import java.util.concurrent.TimeUnit @@ -17,9 +17,9 @@ itemRemoved("staff_of_light*", EquipSlot.Weapon, "worn_equipment") { player -> player.softTimers.stop("power_of_light") } -combatHit { player -> +combatDamage { player -> if (player.softTimers.contains("power_of_light")) { - player.gfx("power_of_light_hit") + player.gfx("power_of_light_impact") } } diff --git a/game/src/main/kotlin/content/skill/melee/weapon/special/StatiusWarhammer.kts b/game/src/main/kotlin/content/skill/melee/weapon/special/StatiusWarhammer.kts index f5ccc80bee..9bf43448f8 100644 --- a/game/src/main/kotlin/content/skill/melee/weapon/special/StatiusWarhammer.kts +++ b/game/src/main/kotlin/content/skill/melee/weapon/special/StatiusWarhammer.kts @@ -1,8 +1,8 @@ package content.skill.melee.weapon.special import world.gregs.voidps.engine.entity.character.player.skill.Skill -import content.entity.player.combat.special.specialAttackHit +import content.entity.player.combat.special.specialAttackDamage -specialAttackHit("smash") { +specialAttackDamage("smash") { target.levels.drain(Skill.Defence, multiplier = 0.30) } \ No newline at end of file diff --git a/game/src/main/kotlin/content/skill/melee/weapon/special/VestasSpear.kts b/game/src/main/kotlin/content/skill/melee/weapon/special/VestasSpear.kts index ee7212ded4..a7bfbe08bb 100644 --- a/game/src/main/kotlin/content/skill/melee/weapon/special/VestasSpear.kts +++ b/game/src/main/kotlin/content/skill/melee/weapon/special/VestasSpear.kts @@ -10,15 +10,15 @@ import world.gregs.voidps.engine.map.spiral import content.entity.combat.Target import content.entity.combat.hit.hit import content.area.wilderness.inMultiCombat -import content.entity.player.combat.special.specialAttackHit +import content.entity.player.combat.special.specialAttackDamage val players: Players by inject() val npcs: NPCs by inject() -specialAttackHit("spear_wall", noHit = false) { player -> +specialAttackDamage("spear_wall", noHit = false) { player -> player.start(id, duration = 8) if (!player.inMultiCombat) { - return@specialAttackHit + return@specialAttackDamage } var remaining = 15 val characters: CharacterList<*> = if (target is Player) players else npcs @@ -29,7 +29,7 @@ specialAttackHit("spear_wall", noHit = false) { player -> } player.hit(char) if (--remaining <= 0) { - return@specialAttackHit + return@specialAttackDamage } } } diff --git a/game/src/main/kotlin/content/skill/melee/weapon/special/ZamorakGodsword.kts b/game/src/main/kotlin/content/skill/melee/weapon/special/ZamorakGodsword.kts index a3dde43837..55d001a564 100644 --- a/game/src/main/kotlin/content/skill/melee/weapon/special/ZamorakGodsword.kts +++ b/game/src/main/kotlin/content/skill/melee/weapon/special/ZamorakGodsword.kts @@ -2,9 +2,9 @@ package content.skill.melee.weapon.special import world.gregs.voidps.engine.timer.toTicks import content.entity.effect.freeze -import content.entity.player.combat.special.specialAttackHit +import content.entity.player.combat.special.specialAttackDamage import java.util.concurrent.TimeUnit -specialAttackHit("ice_cleave") { player -> +specialAttackDamage("ice_cleave") { player -> player.freeze(target, TimeUnit.SECONDS.toTicks(20)) } \ No newline at end of file diff --git a/game/src/main/kotlin/content/skill/mining/CoalBag.kts b/game/src/main/kotlin/content/skill/mining/CoalBag.kts index 3c207abb72..2546dcee95 100644 --- a/game/src/main/kotlin/content/skill/mining/CoalBag.kts +++ b/game/src/main/kotlin/content/skill/mining/CoalBag.kts @@ -50,12 +50,11 @@ inventoryItem("Withdraw-many", "coal_bag") { } itemOnItem("coal", "coal_bag") { player -> - val count = player.inventory.count("coal") - if (count == bagCapacity) { + val coal = player["coal_bag_coal", 0] + if (coal == bagCapacity) { player.message("The coal bag is already full.") return@itemOnItem } - val coal = player["coal_bag_coal", 0] val limit = bagCapacity - coal val removed = player.inventory.removeToLimit("coal", limit) if (removed == 0) { diff --git a/game/src/main/kotlin/content/skill/prayer/active/Leech.kts b/game/src/main/kotlin/content/skill/prayer/active/Leech.kts index 4ff451b74f..7f4efc0333 100644 --- a/game/src/main/kotlin/content/skill/prayer/active/Leech.kts +++ b/game/src/main/kotlin/content/skill/prayer/active/Leech.kts @@ -11,8 +11,8 @@ import world.gregs.voidps.engine.queue.queue import world.gregs.voidps.engine.timer.timerStart import world.gregs.voidps.engine.timer.timerTick import world.gregs.voidps.type.random -import content.entity.combat.hit.characterCombatHit -import content.entity.combat.hit.combatHit +import content.entity.combat.hit.characterCombatDamage +import content.entity.combat.hit.combatDamage import content.entity.player.combat.special.MAX_SPECIAL_ATTACK import content.entity.player.combat.special.specialAttackEnergy import content.entity.player.effect.energy.MAX_RUN_ENERGY @@ -60,35 +60,35 @@ fun getLevel(target: Character, skill: Skill): Int { return target.levels.getMax(skill) } -combatHit { target -> +combatDamage { target -> if (source !is Player || !source.praying("sap_spirit")) { - return@combatHit + return@combatDamage } if (random.nextDouble() >= 0.25) { - return@combatHit + return@combatDamage } val player = source val energy = target.specialAttackEnergy if (energy <= 0) { weakMessage(player, true, "spirit") - return@combatHit + return@combatDamage } target.specialAttackEnergy = (energy - (MAX_SPECIAL_ATTACK / 10)).coerceAtLeast(0) cast(player, target, true, "spirit") } -combatHit { target -> +combatDamage { target -> if (source !is Player || !source.praying("special_attack")) { - return@combatHit + return@combatDamage } if (random.nextDouble() >= 0.15) { - return@combatHit + return@combatDamage } val player = source var energy = target.specialAttackEnergy if (energy <= 0) { weakMessage(player, true, "spirit") - return@combatHit + return@combatDamage } val amount = MAX_SPECIAL_ATTACK / 10 target.specialAttackEnergy = (energy - amount).coerceAtLeast(0) @@ -97,24 +97,24 @@ combatHit { target -> energy = player.specialAttackEnergy if (energy == MAX_SPECIAL_ATTACK) { drainMessage(player, "special_attack") - return@combatHit + return@combatDamage } player.specialAttackEnergy = (energy + amount).coerceAtMost(MAX_SPECIAL_ATTACK) boostMessage(player, "Special Attack") } -combatHit { target -> +combatDamage { target -> if (source !is Player || !source.praying("leech_energy")) { - return@combatHit + return@combatDamage } if (random.nextDouble() >= 0.15) { - return@combatHit + return@combatDamage } val player = source var energy = target.runEnergy if (energy <= 0) { weakMessage(player, false, "run_energy") - return@combatHit + return@combatDamage } val amount = MAX_RUN_ENERGY / 10 target.runEnergy = energy - amount @@ -123,7 +123,7 @@ combatHit { target -> energy = player.runEnergy if (energy == MAX_RUN_ENERGY) { drainMessage(player, "run_energy") - return@combatHit + return@combatDamage } target.runEnergy = energy + amount boostMessage(player, "Run Energy") @@ -149,7 +149,7 @@ val map = mapOf( "leech_magic" to Skill.Magic ) -characterCombatHit { target -> +characterCombatDamage { target -> for ((prayer, skill) in map) { if (!source.praying(prayer)) { continue diff --git a/game/src/main/kotlin/content/skill/prayer/active/SoulSplit.kts b/game/src/main/kotlin/content/skill/prayer/active/SoulSplit.kts index 2b4ae8144e..79775b89c2 100644 --- a/game/src/main/kotlin/content/skill/prayer/active/SoulSplit.kts +++ b/game/src/main/kotlin/content/skill/prayer/active/SoulSplit.kts @@ -22,7 +22,7 @@ combatAttack { player -> target["soul_split_delay"] = CLIENT_TICKS.toTicks(time) target["soul_split_source"] = player target["soul_split_damage"] = damage - target.gfx("soul_split_hit", time) + target.gfx("soul_split_impact", time) target.softTimers.start("soul_split") } diff --git a/game/src/main/kotlin/content/skill/prayer/list/QuickPrayers.kts b/game/src/main/kotlin/content/skill/prayer/list/QuickPrayers.kts index 9addc7453c..cd67c2505b 100644 --- a/game/src/main/kotlin/content/skill/prayer/list/QuickPrayers.kts +++ b/game/src/main/kotlin/content/skill/prayer/list/QuickPrayers.kts @@ -17,6 +17,7 @@ import content.skill.prayer.PrayerConfigs.SELECTING_QUICK_PRAYERS import content.skill.prayer.PrayerConfigs.TEMP_QUICK_PRAYERS import content.skill.prayer.PrayerConfigs.USING_QUICK_PRAYERS import content.entity.player.modal.Tab +import content.entity.player.modal.tab import content.entity.sound.playSound import content.skill.prayer.getActivePrayerVarKey import content.skill.prayer.isCurses @@ -74,7 +75,7 @@ fun Player.togglePrayer(index: Int, listKey: String, quick: Boolean) { interfaceOption("Select Quick Prayers", "orb", "prayer_orb") { val selecting = player.toggle(SELECTING_QUICK_PRAYERS) if (selecting) { - player["tab"] = Tab.PrayerList.name + player.tab(Tab.PrayerList) player.sendVariable(player.getQuickVarKey()) player[TEMP_QUICK_PRAYERS] = player[player.getQuickVarKey(), 0] } else if (player.contains(TEMP_QUICK_PRAYERS)) { diff --git a/game/src/main/kotlin/content/skill/ranged/weapon/Chinchompa.kts b/game/src/main/kotlin/content/skill/ranged/weapon/Chinchompa.kts index 884bb99f29..75a29ffb29 100644 --- a/game/src/main/kotlin/content/skill/ranged/weapon/Chinchompa.kts +++ b/game/src/main/kotlin/content/skill/ranged/weapon/Chinchompa.kts @@ -2,7 +2,7 @@ package content.skill.ranged.weapon import world.gregs.voidps.engine.entity.character.player.Player import world.gregs.voidps.type.random -import content.entity.combat.hit.characterCombatHit +import content.entity.combat.hit.characterCombatDamage import content.entity.combat.hit.combatAttack import content.entity.combat.hit.directHit import content.area.wilderness.inMultiCombat @@ -10,10 +10,10 @@ import content.skill.melee.weapon.multiTargets import content.entity.sound.playSound import kotlin.random.nextInt -characterCombatHit("*chinchompa", "range") { character -> +characterCombatDamage("*chinchompa", "range") { character -> source as Player source.playSound("chinchompa_explode", delay = 40) - character.gfx("chinchompa_hit") + character.gfx("chinchompa_impact") } combatAttack(type = "range") { source -> diff --git a/game/src/main/kotlin/content/skill/ranged/weapon/special/DarkBow.kts b/game/src/main/kotlin/content/skill/ranged/weapon/special/DarkBow.kts index 7de5912dad..196607d5b6 100644 --- a/game/src/main/kotlin/content/skill/ranged/weapon/special/DarkBow.kts +++ b/game/src/main/kotlin/content/skill/ranged/weapon/special/DarkBow.kts @@ -4,7 +4,7 @@ import world.gregs.voidps.engine.entity.character.Character import world.gregs.voidps.engine.entity.character.player.Player import world.gregs.voidps.engine.entity.distanceTo import content.entity.combat.combatSwing -import content.entity.combat.hit.characterCombatHit +import content.entity.combat.hit.characterCombatDamage import content.entity.combat.hit.hit import content.skill.ranged.ammo import content.entity.player.combat.special.specialAttack @@ -33,10 +33,10 @@ specialAttack("descent_of_darkness") { player -> player.hit(target, delay = time2) } -characterCombatHit("dark_bow*", "range") { character -> +characterCombatDamage("dark_bow*", "range") { character -> source.playSound("descent_of_darkness") source.playSound("descent_of_darkness", delay = 20) - character.gfx("descent_of_${if (source.ammo == "dragon_arrow") "dragons" else "darkness"}_hit") + character.gfx("descent_of_${if (source.ammo == "dragon_arrow") "dragons" else "darkness"}_impact") } combatSwing("dark_bow*", "range") { player -> diff --git a/game/src/main/kotlin/content/skill/ranged/weapon/special/GodBows.kts b/game/src/main/kotlin/content/skill/ranged/weapon/special/GodBows.kts index 3fd262055a..96ade9b84a 100644 --- a/game/src/main/kotlin/content/skill/ranged/weapon/special/GodBows.kts +++ b/game/src/main/kotlin/content/skill/ranged/weapon/special/GodBows.kts @@ -36,15 +36,15 @@ combatAttack("saradomin_bow", handler = specialHandler) combatAttack("guthix_bow", handler = specialHandler) combatAttack("zamorak_bow", handler = specialHandler) -val hitHandler: suspend CombatHit.(Character) -> Unit = { character -> +val hitHandler: suspend CombatDamage.(Character) -> Unit = { character -> if (special) { - character.gfx("${weapon.id}_special_hit") - source.playSound("god_bow_special_hit") + character.gfx("${weapon.id}_special_impact") + source.playSound("god_bow_special_impact") } } -combatHit("saradomin_bow", handler = hitHandler) -combatHit("guthix_bow", handler = hitHandler) -combatHit("zamorak_bow", handler = hitHandler) +combatDamage("saradomin_bow", handler = hitHandler) +combatDamage("guthix_bow", handler = hitHandler) +combatDamage("zamorak_bow", handler = hitHandler) timerStart("restorative_shot", "balanced_shot") { interval = TimeUnit.SECONDS.toTicks(6) diff --git a/game/src/main/kotlin/content/skill/ranged/weapon/special/RuneThrowingAxe.kts b/game/src/main/kotlin/content/skill/ranged/weapon/special/RuneThrowingAxe.kts index be60863ac3..6adc221557 100644 --- a/game/src/main/kotlin/content/skill/ranged/weapon/special/RuneThrowingAxe.kts +++ b/game/src/main/kotlin/content/skill/ranged/weapon/special/RuneThrowingAxe.kts @@ -8,7 +8,7 @@ import world.gregs.voidps.engine.entity.character.player.Players import world.gregs.voidps.engine.inject import world.gregs.voidps.engine.map.spiral import content.entity.combat.Target -import content.entity.combat.hit.characterCombatHit +import content.entity.combat.hit.characterCombatDamage import content.entity.combat.hit.hit import content.area.wilderness.inMultiCombat import content.skill.ranged.ammo @@ -29,9 +29,9 @@ specialAttack("chainhit") { player -> player.hit(target, delay = time) } -characterCombatHit("rune_throwing_axe", "range") { target -> +characterCombatDamage("rune_throwing_axe", "range") { target -> if (source !is Player || !target.inMultiCombat || !special) { - return@characterCombatHit + return@characterCombatDamage } val chain: MutableSet = source.getOrPut("chain_hits") { mutableSetOf() } val characters = if (target is Player) players else npcs @@ -45,12 +45,12 @@ characterCombatHit("rune_throwing_axe", "range") { target -> } if (!SpecialAttack.drain(source)) { source.clear("chain_hits") - return@characterCombatHit + return@characterCombatDamage } chain.add(character.index) val time = target.shoot(id = "rune_throwing_axe_special", target = character) source.hit(character, weapon, type, special = true, delay = time) - return@characterCombatHit + return@characterCombatDamage } } } \ No newline at end of file diff --git a/game/src/main/kotlin/content/skill/ranged/weapon/special/Seercull.kts b/game/src/main/kotlin/content/skill/ranged/weapon/special/Seercull.kts index 84d5430fdc..45d02a0cb5 100644 --- a/game/src/main/kotlin/content/skill/ranged/weapon/special/Seercull.kts +++ b/game/src/main/kotlin/content/skill/ranged/weapon/special/Seercull.kts @@ -2,7 +2,7 @@ package content.skill.ranged.weapon.special import world.gregs.voidps.engine.entity.character.player.skill.Skill import world.gregs.voidps.engine.entity.character.player.skill.level.characterLevelChange -import content.entity.combat.hit.characterCombatHit +import content.entity.combat.hit.characterCombatDamage import content.entity.combat.hit.combatAttack import content.entity.combat.hit.hit import content.entity.player.combat.special.specialAttack @@ -17,8 +17,8 @@ specialAttack("soulshot") { player -> player.hit(target, delay = time) } -characterCombatHit("seercull", "range") { character -> - character.gfx("seercull_special_hit") +characterCombatDamage("seercull", "range") { character -> + character.gfx("seercull_special_impact") } combatAttack("seercull*") { diff --git a/game/src/main/kotlin/content/skill/runecrafting/EssenceMine.kt b/game/src/main/kotlin/content/skill/runecrafting/EssenceMine.kt index 7a3f2c98b4..ed1b478e8b 100644 --- a/game/src/main/kotlin/content/skill/runecrafting/EssenceMine.kt +++ b/game/src/main/kotlin/content/skill/runecrafting/EssenceMine.kt @@ -20,7 +20,7 @@ object EssenceMine { if (!npc.contains("old_model")) { npc.anim("curse") } - player.gfx("curse_hit") + player.gfx("curse_impact") player.shoot("curse", player.tile) player.softQueue("essence_mine_teleport", 3) { player["last_npc_teleport_to_rune_essence_mine"] = npc.id diff --git a/game/src/main/kotlin/content/skill/runecrafting/RuneEssenceMine.kts b/game/src/main/kotlin/content/skill/runecrafting/RuneEssenceMine.kts index 640114cd3b..cf2ce875bc 100644 --- a/game/src/main/kotlin/content/skill/runecrafting/RuneEssenceMine.kts +++ b/game/src/main/kotlin/content/skill/runecrafting/RuneEssenceMine.kts @@ -12,7 +12,7 @@ val areas: AreaDefinitions by inject() objectOperate("Enter", "rune_essence_exit_portal") { player.message("You step through the portal...") - player.gfx("curse_hit", delay = 30) + player.gfx("curse_impact", delay = 30) target.tile.shoot("curse", player.tile) player.softQueue("essence_mine_exit", 3) { diff --git a/game/src/main/kotlin/content/skill/smithing/Furnace.kts b/game/src/main/kotlin/content/skill/smithing/Furnace.kts index 73822da5fe..1541aae21d 100644 --- a/game/src/main/kotlin/content/skill/smithing/Furnace.kts +++ b/game/src/main/kotlin/content/skill/smithing/Furnace.kts @@ -90,7 +90,7 @@ fun smelt(player: Player, target: GameObject, id: String, amount: Int) { } val definition = itemDefinitions.get(id) - val smelting: Smelting = definition["smelting"] + val smelting: Smelting = definition.getOrNull("smelting") ?: return if (!player.has(Skill.Smithing, smelting.level, message = true)) { player.softTimers.stop("smelting") return @@ -113,7 +113,7 @@ fun smelt(player: Player, target: GameObject, id: String, amount: Int) { if (success) { player.exp(Skill.Smithing, smelting.exp(player, id)) player.message("You retrieve a bar of ${id.removeSuffix("_bar")}.") - if (varrockArmour(player, target, id, smelting)) { + if (amount - 1 > 0 && varrockArmour(player, target, id, smelting)) { removed = 2 } } else { diff --git a/game/src/main/kotlin/content/skill/smithing/Smithing.kt b/game/src/main/kotlin/content/skill/smithing/Smithing.kt index 483d35d99c..bfc555928b 100644 --- a/game/src/main/kotlin/content/skill/smithing/Smithing.kt +++ b/game/src/main/kotlin/content/skill/smithing/Smithing.kt @@ -8,12 +8,10 @@ import world.gregs.voidps.network.login.protocol.visual.update.player.EquipSlot import world.gregs.voidps.type.Tile fun Smelting.exp(player: Player, bar: String): Double { - if (bar != "gold_bar") { - return xp + if (bar == "gold_bar" && (player.equipped(EquipSlot.Hands).id == "goldsmith_gauntlets" || player.equipped(EquipSlot.Cape).id.startsWith("smithing_cape"))) { + return 56.2 } - val gloves = player.equipped(EquipSlot.Hands) - val cape = player.equipped(EquipSlot.Cape) - return if (gloves.id == "goldsmith_gauntlets" || cape.id.startsWith("smithing_cape")) 56.2 else xp + return xp } fun oreToBar(ore: String): String { diff --git a/game/src/main/kotlin/content/skill/smithing/SuperheatItem.kts b/game/src/main/kotlin/content/skill/smithing/SuperheatItem.kts index bd8c2cbb9b..065851feb5 100644 --- a/game/src/main/kotlin/content/skill/smithing/SuperheatItem.kts +++ b/game/src/main/kotlin/content/skill/smithing/SuperheatItem.kts @@ -12,7 +12,7 @@ import world.gregs.voidps.engine.inv.inventory import world.gregs.voidps.engine.inv.transact.TransactionError import world.gregs.voidps.engine.inv.transact.operation.AddItem.add import world.gregs.voidps.engine.inv.transact.remove -import content.skill.magic.spell.Spell.removeItems +import content.skill.magic.spell.SpellRunes.removeItems import content.entity.sound.playSound val spellDefinitions: SpellDefinitions by inject() diff --git a/game/src/main/kotlin/content/social/trade/TradeRequest.kts b/game/src/main/kotlin/content/social/trade/TradeRequest.kts index 42524056a4..af2a71137e 100644 --- a/game/src/main/kotlin/content/social/trade/TradeRequest.kts +++ b/game/src/main/kotlin/content/social/trade/TradeRequest.kts @@ -17,6 +17,7 @@ import world.gregs.voidps.engine.inv.moveAll import content.social.friend.friend import content.social.trade.Trade.getPartner import content.entity.player.modal.Tab +import content.entity.player.modal.tab /** * Requesting to trade with another player, accepting the request and setting up the trade @@ -89,7 +90,7 @@ fun reset(player: Player, other: Player) { player.interfaces.close("trade_side") player.interfaces.open("inventory") - player["tab"] = Tab.Inventory.name + player.tab(Tab.Inventory) player["offer_value"] = 0 player["other_offer_value"] = 0 player["lend_time"] = 0 diff --git a/game/src/test/kotlin/InstructionCalls.kt b/game/src/test/kotlin/InstructionCalls.kt index 0a3df96aaf..abe15d013b 100644 --- a/game/src/test/kotlin/InstructionCalls.kt +++ b/game/src/test/kotlin/InstructionCalls.kt @@ -4,6 +4,7 @@ import world.gregs.voidps.engine.client.ui.InterfaceOption import world.gregs.voidps.engine.client.ui.InterfaceSwitch import world.gregs.voidps.engine.client.ui.dialogue import world.gregs.voidps.engine.client.ui.dialogue.ContinueDialogue +import world.gregs.voidps.engine.client.ui.event.IntEntered import world.gregs.voidps.engine.client.ui.hasOpen import world.gregs.voidps.engine.client.ui.interact.ItemOnItem import world.gregs.voidps.engine.client.ui.interact.ItemOnObject @@ -35,14 +36,18 @@ fun Player.itemOption( slot: Int = inventories.inventory(inventory).indexOf(item) ) { Assertions.assertTrue(hasOpen(id)) { "Player $this doesn't have interface $id open" } - emit(InterfaceOption(this, - id = id, - component = component, - optionIndex = optionIndex, - option = option, - item = inventories.inventory(inventory).getOrNull(slot) ?: Item(item), - itemSlot = slot, - inventory = inventory)) + emit( + InterfaceOption( + this, + id = id, + component = component, + optionIndex = optionIndex, + option = option, + item = inventories.inventory(inventory).getOrNull(slot) ?: Item(item), + itemSlot = slot, + inventory = inventory + ) + ) } fun Player.interfaceOption( @@ -58,6 +63,22 @@ fun Player.interfaceOption( emit(InterfaceOption(this, id = id, component = component, optionIndex = optionIndex, option = option, item = item, itemSlot = slot, inventory = inventory)) } +fun Player.skillCreation( + item: String, + amount: Int = 1 +) { + Assertions.assertTrue(hasOpen("dialogue_skill_creation")) { "Player $this doesn't have interface dialogue_skill_creation open" } + set("skill_creation_amount", amount) + var index = -1 + for (i in 0 until 10) { + val name = get("skill_creation_name_$i") ?: continue + if (item == name) { + index = i + } + } + emit(IntEntered(index)) +} + fun Player.interfaceUse( id: String, component: String, @@ -68,18 +89,20 @@ fun Player.interfaceUse( toSlot: Int = -1 ) { Assertions.assertTrue(hasOpen(id)) { "Player $this doesn't have interface $id open" } - emit(ItemOnItem( - fromItem = fromItem, - toItem = toItem, - fromSlot = fromSlot, - toSlot = toSlot, - fromInterface = id, - fromComponent = component, - toInterface = id, - toComponent = component, - fromInventory = inventory, - toInventory = inventory - )) + emit( + ItemOnItem( + fromItem = fromItem, + toItem = toItem, + fromSlot = fromSlot, + toSlot = toSlot, + fromInterface = id, + fromComponent = component, + toInterface = id, + toComponent = component, + fromInventory = inventory, + toInventory = inventory + ) + ) } fun Player.interfaceSwitch( @@ -92,18 +115,20 @@ fun Player.interfaceSwitch( toSlot: Int = -1 ) { Assertions.assertTrue(hasOpen(id)) { "Player $this doesn't have interface $id open" } - emit(InterfaceSwitch( - id = id, - component = component, - fromItem = fromItem, - fromSlot = fromSlot, - fromInventory = inventory, - toId = id, - toComponent = component, - toItem = toItem, - toSlot = toSlot, - toInventory = inventory - )) + emit( + InterfaceSwitch( + id = id, + component = component, + fromItem = fromItem, + fromSlot = fromSlot, + fromInventory = inventory, + toId = id, + toComponent = component, + toItem = toItem, + toSlot = toSlot, + toInventory = inventory + ) + ) } fun Player.equipItem( @@ -167,18 +192,20 @@ fun Player.itemOnItem( ) { val one = inventories.inventory(firstInventory) val two = inventories.inventory(secondInventory) - emit(ItemOnItem( - one[firstSlot], - two[secondSlot], - firstSlot, - secondSlot, - firstInventory, - firstComponent, - secondInventory, - secondComponent, - firstInventory, - secondInventory - )) + emit( + ItemOnItem( + one[firstSlot], + two[secondSlot], + firstSlot, + secondSlot, + firstInventory, + firstComponent, + secondInventory, + secondComponent, + firstInventory, + secondInventory + ) + ) } fun Player.npcOption(npc: NPC, option: String) = npcOption(npc, npc.def.options.indexOf(option)) diff --git a/game/src/test/kotlin/content/entity/combat/CombatTest.kt b/game/src/test/kotlin/content/entity/combat/CombatTest.kt index 4c710ed677..798268929a 100644 --- a/game/src/test/kotlin/content/entity/combat/CombatTest.kt +++ b/game/src/test/kotlin/content/entity/combat/CombatTest.kt @@ -16,7 +16,7 @@ import world.gregs.voidps.network.client.instruction.InteractPlayer import world.gregs.voidps.network.login.protocol.visual.update.player.EquipSlot import world.gregs.voidps.type.Tile import world.gregs.voidps.type.setRandom -import content.entity.combat.hit.npcCombatHit +import content.entity.combat.hit.npcCombatDamage import equipItem import interfaceOption import npcOption @@ -113,7 +113,7 @@ internal class CombatTest : WorldTest() { @Test fun `Dragon dagger special attack`() { var hits = 0 - npcCombatHit { + npcCombatDamage { hits++ } val player = createPlayer("player", emptyTile) diff --git a/game/src/test/kotlin/content/entity/player/WeakInteractionTest.kt b/game/src/test/kotlin/content/entity/player/WeakInteractionTest.kt index e8a80546df..fd7ae26d76 100644 --- a/game/src/test/kotlin/content/entity/player/WeakInteractionTest.kt +++ b/game/src/test/kotlin/content/entity/player/WeakInteractionTest.kt @@ -47,7 +47,7 @@ internal class WeakInteractionTest : WorldTest() { when (it) { "Interface switch" -> { - val wool = Item("ball_of_wool", 1) + val wool = Item("ball_of_wool") player.interfaceSwitch("inventory", "inventory", "inventory", wool, wool, 0, 1) } "Remove equipment" -> player.interfaceOption("worn_equipment", "weapon_slot", "*", 0, Item("bronze_sword")) @@ -96,7 +96,7 @@ internal class WeakInteractionTest : WorldTest() { val target = player.tile.addY(10) player.walk(target) tick(4) - player.interfaceOption("inventory", "inventory", "Drop", 4, Item("vial", 1), 0) + player.interfaceOption("inventory", "inventory", "Drop", 4, Item("vial"), 0) tick(6) assertEquals(target, player.tile) diff --git a/game/src/test/kotlin/content/entity/player/bank/BankTest.kt b/game/src/test/kotlin/content/entity/player/bank/BankTest.kt index 47ac56a167..30f8c1d64a 100644 --- a/game/src/test/kotlin/content/entity/player/bank/BankTest.kt +++ b/game/src/test/kotlin/content/entity/player/bank/BankTest.kt @@ -82,7 +82,7 @@ internal class BankTest : WorldTest() { assertTrue(player.equipment.isEmpty()) assertEquals(Item("rune_arrow", 100), player.bank[1]) - assertEquals(Item("ranged_cape", 1), player.bank[0]) + assertEquals(Item("ranged_cape"), player.bank[0]) } @Test @@ -99,8 +99,8 @@ internal class BankTest : WorldTest() { player.interfaceOption("bank", "inventory", "Withdraw-1", item = Item("bronze_sword"), slot = 0) assertEquals(Item("coins", 1000), player.inventory[0]) - assertEquals(Item("bronze_sword", 1), player.inventory[1]) - assertEquals(Item("bronze_sword", 1), player.inventory[2]) + assertEquals(Item("bronze_sword"), player.inventory[1]) + assertEquals(Item("bronze_sword"), player.inventory[2]) assertEquals(Item("bronze_sword", 8), player.bank[0]) } diff --git a/game/src/test/kotlin/content/entity/player/equip/EquipTest.kt b/game/src/test/kotlin/content/entity/player/equip/EquipTest.kt index 3538527e5b..70d7ab4f7a 100644 --- a/game/src/test/kotlin/content/entity/player/equip/EquipTest.kt +++ b/game/src/test/kotlin/content/entity/player/equip/EquipTest.kt @@ -24,7 +24,7 @@ internal class EquipTest : WorldTest() { player.interfaceOption("inventory", "inventory", "Wield", 1, Item("bronze_sword"), 0) - assertEquals(Item("bronze_sword", 1), player.equipped(EquipSlot.Weapon)) + assertEquals(Item("bronze_sword"), player.equipped(EquipSlot.Weapon)) assertEquals(1, player.inventory.spaces) } @@ -37,7 +37,7 @@ internal class EquipTest : WorldTest() { player.interfaceOption("inventory", "inventory", "Wield", 1, Item("bronze_2h_sword"), 0) - assertEquals(Item("bronze_2h_sword", 1), player.equipped(EquipSlot.Weapon)) + assertEquals(Item("bronze_2h_sword"), player.equipped(EquipSlot.Weapon)) assertTrue(player.inventory.contains("bronze_sword")) } @@ -50,7 +50,7 @@ internal class EquipTest : WorldTest() { player.interfaceOption("inventory", "inventory", "Wield", 1, Item("bronze_2h_sword"), 0) - assertEquals(Item("bronze_2h_sword", 1), player.equipped(EquipSlot.Weapon)) + assertEquals(Item("bronze_2h_sword"), player.equipped(EquipSlot.Weapon)) assertTrue(player.equipped(EquipSlot.Shield).isEmpty()) assertTrue(player.inventory.contains("bronze_sq_shield")) } @@ -65,7 +65,7 @@ internal class EquipTest : WorldTest() { player.interfaceOption("inventory", "inventory", "Wield", 1, Item("bronze_2h_sword"), 0) - assertEquals(Item("bronze_2h_sword", 1), player.equipped(EquipSlot.Weapon)) + assertEquals(Item("bronze_2h_sword"), player.equipped(EquipSlot.Weapon)) assertTrue(player.equipped(EquipSlot.Shield).isEmpty()) assertTrue(player.inventory.contains("bronze_sword")) assertTrue(player.inventory.contains("bronze_sq_shield")) @@ -81,8 +81,8 @@ internal class EquipTest : WorldTest() { player.interfaceOption("inventory", "inventory", "Wield", 1, Item("bronze_2h_sword"), 0) - assertEquals(Item("bronze_sword", 1), player.equipped(EquipSlot.Weapon)) - assertEquals(Item("bronze_sq_shield", 1), player.equipped(EquipSlot.Shield)) + assertEquals(Item("bronze_sword"), player.equipped(EquipSlot.Weapon)) + assertEquals(Item("bronze_sq_shield"), player.equipped(EquipSlot.Shield)) assertTrue(player.inventory.contains("bronze_2h_sword")) } @@ -95,7 +95,7 @@ internal class EquipTest : WorldTest() { player.interfaceOption("inventory", "inventory", "Wield", 1, Item("bronze_sword"), 0) - assertEquals(Item("bronze_sword", 1), player.equipped(EquipSlot.Weapon)) + assertEquals(Item("bronze_sword"), player.equipped(EquipSlot.Weapon)) assertTrue(player.inventory.contains("bronze_2h_sword")) } @@ -109,7 +109,7 @@ internal class EquipTest : WorldTest() { player.interfaceOption("inventory", "inventory", "Wield", 1, Item("bronze_sq_shield"), 0) assertTrue(player.equipped(EquipSlot.Weapon).isEmpty()) - assertEquals(Item("bronze_sq_shield", 1), player.equipped(EquipSlot.Shield)) + assertEquals(Item("bronze_sq_shield"), player.equipped(EquipSlot.Shield)) assertTrue(player.inventory.contains("bronze_2h_sword")) } diff --git a/game/src/test/kotlin/content/entity/player/inv/DropTest.kt b/game/src/test/kotlin/content/entity/player/inv/DropTest.kt index b69684bed4..56c5640b04 100644 --- a/game/src/test/kotlin/content/entity/player/inv/DropTest.kt +++ b/game/src/test/kotlin/content/entity/player/inv/DropTest.kt @@ -20,25 +20,12 @@ internal class DropTest : WorldTest() { val player = createPlayer("player") player.inventory.add("bronze_sword") - player.interfaceOption("inventory", "inventory", "Drop", 4, Item("bronze_sword", 1), 0) + player.interfaceOption("inventory", "inventory", "Drop", 4, Item("bronze_sword"), 0) assertTrue(player.inventory.isEmpty()) assertTrue(floorItems[player.tile].any { it.id == "bronze_sword" }) } - @Test - fun `Pickup item off the floor`() { - val tile = emptyTile - val player = createPlayer("player", tile) - val item = floorItems.add(tile.add(0, 2), "bronze_sword") - - player.floorItemOption(item, "Take") - tick(5) - - assertTrue(player.inventory.contains("bronze_sword")) - assertTrue(floorItems[tile.add(0, 2)].isEmpty()) - } - @Test fun `Floor item respawns after delay`() { val tile = Tile(3244, 3157) @@ -74,7 +61,7 @@ internal class DropTest : WorldTest() { floorItems.add(tile, "bronze_sword") player.inventory.add("bronze_sword") - player.interfaceOption("inventory", "inventory", "Drop", 4, Item("bronze_sword", 1), 0) + player.interfaceOption("inventory", "inventory", "Drop", 4, Item("bronze_sword"), 0) assertTrue(player.inventory.isEmpty()) assertEquals(2, floorItems[tile].count { it.id == "bronze_sword" }) @@ -105,18 +92,4 @@ internal class DropTest : WorldTest() { assertFalse(floorItems[tile.addX(1)].any { it.id == "toolkit" }) } - @Test - fun `Pickup item up off a table`() { - val tile = Tile(3212, 3218, 1) - val player = createPlayer("player", tile) - val item = floorItems.add(tile.add(1, 0), "bronze_sword") - - player.floorItemOption(item, "Take") - tick(5) - - assertTrue(player.inventory.contains("bronze_sword")) - assertTrue(floorItems[tile.add(1, 0)].isEmpty()) - assertEquals(tile, player.tile) - } - } \ No newline at end of file diff --git a/game/src/test/kotlin/content/entity/player/inv/TakeTest.kt b/game/src/test/kotlin/content/entity/player/inv/TakeTest.kt new file mode 100644 index 0000000000..e3f7b55698 --- /dev/null +++ b/game/src/test/kotlin/content/entity/player/inv/TakeTest.kt @@ -0,0 +1,45 @@ +package content.entity.player.inv + +import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.Assertions.assertTrue +import org.junit.jupiter.api.Test +import world.gregs.voidps.engine.entity.item.Item +import world.gregs.voidps.engine.inv.add +import world.gregs.voidps.engine.inv.inventory +import world.gregs.voidps.type.Tile +import WorldTest +import floorItemOption +import interfaceOption +import itemOnObject +import kotlin.test.assertFalse + +internal class TakeTest : WorldTest() { + + @Test + fun `Take item off the floor`() { + val tile = emptyTile + val player = createPlayer("player", tile) + val item = floorItems.add(tile.add(0, 2), "bronze_sword") + + player.floorItemOption(item, "Take") + tick(5) + + assertTrue(player.inventory.contains("bronze_sword")) + assertTrue(floorItems[tile.add(0, 2)].isEmpty()) + } + + @Test + fun `Take item up off a table`() { + val tile = Tile(3212, 3218, 1) + val player = createPlayer("player", tile) + val item = floorItems.add(tile.add(1, 0), "bronze_sword") + + player.floorItemOption(item, "Take") + tick(5) + + assertTrue(player.inventory.contains("bronze_sword")) + assertTrue(floorItems[tile.add(1, 0)].isEmpty()) + assertEquals(tile, player.tile) + } + +} \ No newline at end of file diff --git a/game/src/test/kotlin/content/entity/player/kept/PriceCheckerTest.kt b/game/src/test/kotlin/content/entity/player/kept/PriceCheckerTest.kt index 6ed3dfb064..bcfe8a74d7 100644 --- a/game/src/test/kotlin/content/entity/player/kept/PriceCheckerTest.kt +++ b/game/src/test/kotlin/content/entity/player/kept/PriceCheckerTest.kt @@ -19,10 +19,10 @@ internal class PriceCheckerTest : WorldTest() { player.inventory.add("bronze_sword") player.interfaceOption("worn_equipment", "price", "Show Price-checker") - player.interfaceOption("price_checker_side", "items", "Add", 0, Item("bronze_sword", 1), slot = 0, inventory = "inventory") + player.interfaceOption("price_checker_side", "items", "Add", 0, Item("bronze_sword"), slot = 0, inventory = "inventory") assertTrue(player.inventory[0].isEmpty()) - assertEquals(Item("bronze_sword", 1), player.offer[0]) + assertEquals(Item("bronze_sword"), player.offer[0]) } @Test @@ -31,10 +31,10 @@ internal class PriceCheckerTest : WorldTest() { player.inventory.add("bronze_sword") player.interfaceOption("worn_equipment", "price", "Show Price-checker") - player.interfaceOption("price_checker_side", "items", "Add", 0, Item("bronze_sword", 1), slot = 0, inventory = "inventory") - player.interfaceOption("price_checker", "items", "Remove-1", 0, Item("bronze_sword", 1), slot = 0, inventory = "trade_offer") + player.interfaceOption("price_checker_side", "items", "Add", 0, Item("bronze_sword"), slot = 0, inventory = "inventory") + player.interfaceOption("price_checker", "items", "Remove-1", 0, Item("bronze_sword"), slot = 0, inventory = "trade_offer") - assertEquals(Item("bronze_sword", 1), player.inventory[0]) + assertEquals(Item("bronze_sword"), player.inventory[0]) assertTrue(player.offer[0].isEmpty()) } @@ -44,11 +44,11 @@ internal class PriceCheckerTest : WorldTest() { player.inventory.add("bronze_sword") player.interfaceOption("worn_equipment", "price", "Show Price-checker") - player.interfaceOption("price_checker_side", "items", "Add", 0, Item("bronze_sword", 1), slot = 0, inventory = "inventory") + player.interfaceOption("price_checker_side", "items", "Add", 0, Item("bronze_sword"), slot = 0, inventory = "inventory") player.walk(player.tile.addX(1)) tick() - assertEquals(Item("bronze_sword", 1), player.inventory[0]) + assertEquals(Item("bronze_sword"), player.inventory[0]) assertTrue(player.offer.isEmpty()) } } \ No newline at end of file diff --git a/game/src/test/kotlin/content/skill/course/BarbarianAdvancedTest.kt b/game/src/test/kotlin/content/skill/agility/course/BarbarianAdvancedTest.kt similarity index 98% rename from game/src/test/kotlin/content/skill/course/BarbarianAdvancedTest.kt rename to game/src/test/kotlin/content/skill/agility/course/BarbarianAdvancedTest.kt index 8b6cac45c0..aa81ec7b34 100644 --- a/game/src/test/kotlin/content/skill/course/BarbarianAdvancedTest.kt +++ b/game/src/test/kotlin/content/skill/agility/course/BarbarianAdvancedTest.kt @@ -1,4 +1,4 @@ -package content.skill.course +package content.skill.agility.course import content.skill.agility.course.agilityCourse import content.skill.agility.course.agilityStage diff --git a/game/src/test/kotlin/content/skill/course/BarbarianOutpostTest.kt b/game/src/test/kotlin/content/skill/agility/course/BarbarianOutpostTest.kt similarity index 99% rename from game/src/test/kotlin/content/skill/course/BarbarianOutpostTest.kt rename to game/src/test/kotlin/content/skill/agility/course/BarbarianOutpostTest.kt index f0120b38a5..095390a659 100644 --- a/game/src/test/kotlin/content/skill/course/BarbarianOutpostTest.kt +++ b/game/src/test/kotlin/content/skill/agility/course/BarbarianOutpostTest.kt @@ -1,4 +1,4 @@ -package content.skill.course +package content.skill.agility.course import content.skill.agility.course.agilityCourse import content.skill.agility.course.agilityStage diff --git a/game/src/test/kotlin/content/skill/course/GnomeAdvancedTest.kt b/game/src/test/kotlin/content/skill/agility/course/GnomeAdvancedTest.kt similarity index 99% rename from game/src/test/kotlin/content/skill/course/GnomeAdvancedTest.kt rename to game/src/test/kotlin/content/skill/agility/course/GnomeAdvancedTest.kt index 1b8f514789..949b9676ab 100644 --- a/game/src/test/kotlin/content/skill/course/GnomeAdvancedTest.kt +++ b/game/src/test/kotlin/content/skill/agility/course/GnomeAdvancedTest.kt @@ -1,4 +1,4 @@ -package content.skill.course +package content.skill.agility.course import content.skill.agility.course.agilityCourse import content.skill.agility.course.agilityStage diff --git a/game/src/test/kotlin/content/skill/course/GnomeStrongholdTest.kt b/game/src/test/kotlin/content/skill/agility/course/GnomeStrongholdTest.kt similarity index 99% rename from game/src/test/kotlin/content/skill/course/GnomeStrongholdTest.kt rename to game/src/test/kotlin/content/skill/agility/course/GnomeStrongholdTest.kt index 5641eb2c4b..0130fa75d6 100644 --- a/game/src/test/kotlin/content/skill/course/GnomeStrongholdTest.kt +++ b/game/src/test/kotlin/content/skill/agility/course/GnomeStrongholdTest.kt @@ -1,4 +1,4 @@ -package content.skill.course +package content.skill.agility.course import WorldTest import content.skill.agility.course.agilityCourse diff --git a/game/src/test/kotlin/content/skill/course/WildernessCourseTest.kt b/game/src/test/kotlin/content/skill/agility/course/WildernessCourseTest.kt similarity index 99% rename from game/src/test/kotlin/content/skill/course/WildernessCourseTest.kt rename to game/src/test/kotlin/content/skill/agility/course/WildernessCourseTest.kt index 8ddfef41f2..c17e8304cd 100644 --- a/game/src/test/kotlin/content/skill/course/WildernessCourseTest.kt +++ b/game/src/test/kotlin/content/skill/agility/course/WildernessCourseTest.kt @@ -1,4 +1,4 @@ -package content.skill.course +package content.skill.agility.course import content.skill.agility.course.agilityCourse import content.skill.agility.course.agilityStage diff --git a/game/src/test/kotlin/content/skill/crafting/JewelleryTest.kt b/game/src/test/kotlin/content/skill/crafting/JewelleryTest.kt new file mode 100644 index 0000000000..540066491f --- /dev/null +++ b/game/src/test/kotlin/content/skill/crafting/JewelleryTest.kt @@ -0,0 +1,221 @@ +package content.skill.crafting + +import WorldTest +import containsMessage +import content.entity.player.dialogue.continueDialogue +import interfaceOption +import itemOnObject +import net.pearx.kasechange.toLowerSpaceCase +import org.junit.jupiter.api.Assertions.assertNotEquals +import org.junit.jupiter.api.Assertions.assertTrue +import org.junit.jupiter.api.DynamicTest.dynamicTest +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.TestFactory +import world.gregs.voidps.engine.client.ui.event.IntEntered +import world.gregs.voidps.engine.entity.character.player.skill.Skill +import world.gregs.voidps.engine.inv.add +import world.gregs.voidps.engine.inv.inventory +import world.gregs.voidps.type.Tile +import kotlin.test.assertEquals + +class JewelleryTest : WorldTest() { + + private val moulds = listOf("ring", "necklace", "amulet_unstrung", "bracelet") + private val gems = listOf("sapphire", "emerald", "ruby", "diamond", "dragonstone", "onyx") + + @TestFactory + fun `Make gold jewellery`() = moulds.map { type -> + dynamicTest("Make gold ${type.toLowerSpaceCase()}") { + val player = createPlayer("Crafter", Tile(3227, 3255)) + player.levels.set(Skill.Crafting, 10) + player.inventory.add("${type}_mould", "gold_bar") + val furnace = objects[Tile(3226, 3256), "furnace_lumbridge"]!! + + player.itemOnObject(furnace, 0, "${type}_mould") + tick() + + player.interfaceOption("make_mould_slayer", "make_${type}_option_gold", "Make 1") + tick(3) + + assertEquals(0, player.inventory.count("gold_bar")) + assertEquals(1, player.inventory.count("${type}_mould")) + assertEquals(1, player.inventory.count("gold_${type}")) + assertNotEquals(0.0, player.experience.get(Skill.Crafting)) + } + } + @Test + fun `Make ring of slaying`() { + val player = createPlayer("Crafter", Tile(3227, 3255)) + player.levels.set(Skill.Crafting, 75) + player.inventory.add("ring_mould", "gold_bar", "enchanted_gem") + val furnace = objects[Tile(3226, 3256), "furnace_lumbridge"]!! + + player.itemOnObject(furnace, 0, "ring_mould") + tick() + + player.interfaceOption("make_mould_slayer", "make_ring_option_enchanted_gem", "Make 1") + tick(3) + + assertEquals(0, player.inventory.count("gold_bar")) + assertEquals(1, player.inventory.count("ring_mould")) + assertEquals(1, player.inventory.count("ring_of_slaying_8")) + assertEquals(15.0, player.experience.get(Skill.Crafting)) + } + + @TestFactory + fun `Make gem jewellery`() = gems.flatMap { gem -> + moulds.map { type -> + dynamicTest("Make $gem ${type.toLowerSpaceCase()}") { + val player = createPlayer("Crafter", Tile(3227, 3255)) + player.levels.set(Skill.Crafting, 99) + player.inventory.add("${type}_mould", "gold_bar", gem) + val furnace = objects[Tile(3226, 3256), "furnace_lumbridge"]!! + + player.itemOnObject(furnace, 0, "${type}_mould") + tick() + + player.interfaceOption("make_mould_slayer", "make_${type}_option_${gem}", "Make 1") + tick(3) + + assertEquals(0, player.inventory.count("gold_bar")) + assertEquals(0, player.inventory.count(gem)) + assertEquals(1, player.inventory.count("${type}_mould")) + assertEquals(1, player.inventory.count("${gem}_${type}")) + assertNotEquals(0.0, player.experience.get(Skill.Crafting)) + } + } + } + + @Test + fun `Can't make gem jewellery without a gem`() { + val player = createPlayer("Crafter", Tile(3227, 3255)) + player.levels.set(Skill.Crafting, 99) + player.inventory.add("necklace_mould", "gold_bar") + val furnace = objects[Tile(3226, 3256), "furnace_lumbridge"]!! + + player.itemOnObject(furnace, 0, "necklace_mould") + tick() + + player.interfaceOption("make_mould_slayer", "make_necklace_option_emerald", "Make 1") + tick(3) + + assertEquals(1, player.inventory.count("gold_bar")) + assertEquals(0, player.inventory.count("emerald")) + assertEquals(1, player.inventory.count("necklace_mould")) + assertEquals(0, player.inventory.count("emerald_necklace")) + assertEquals(0.0, player.experience.get(Skill.Crafting)) + } + + @Test + fun `Make 5 with more than in inventory`() { + val player = createPlayer("Crafter", Tile(3227, 3255)) + player.levels.set(Skill.Crafting, 99) + player.inventory.add("bracelet_mould") + player.inventory.add("gold_bar", 6) + player.inventory.add("ruby", 6) + val furnace = objects[Tile(3226, 3256), "furnace_lumbridge"]!! + + player.itemOnObject(furnace, 0, "bracelet_mould") + tick() + + player.interfaceOption("make_mould_slayer", "make_bracelet_option_ruby", "Make 5") + tick(12) + assertEquals(2, player.inventory.count("gold_bar")) + assertEquals(2, player.inventory.count("ruby")) + tick(3) + + assertEquals(1, player.inventory.count("gold_bar")) + assertEquals(1, player.inventory.count("bracelet_mould")) + assertEquals(1, player.inventory.count("ruby")) + assertEquals(5, player.inventory.count("ruby_bracelet")) + assertEquals(400.0, player.experience.get(Skill.Crafting)) + } + + @Test + fun `Make All with extra gold bar`() { + val player = createPlayer("Crafter", Tile(3227, 3255)) + player.levels.set(Skill.Crafting, 99) + player.inventory.add("bracelet_mould") + player.inventory.add("gold_bar", 3) + player.inventory.add("ruby", 2) + val furnace = objects[Tile(3226, 3256), "furnace_lumbridge"]!! + + player.itemOnObject(furnace, 0, "bracelet_mould") + tick() + + player.interfaceOption("make_mould_slayer", "make_bracelet_option_ruby", "Make All") + tick(6) + assertEquals(1, player.inventory.count("gold_bar")) + assertEquals(1, player.inventory.count("bracelet_mould")) + assertEquals(0, player.inventory.count("ruby")) + assertEquals(2, player.inventory.count("ruby_bracelet")) + assertNotEquals(0.0, player.experience.get(Skill.Crafting)) + } + + @Test + fun `Make X with missing gem`() { + val player = createPlayer("Crafter", Tile(3227, 3255)) + player.levels.set(Skill.Crafting, 99) + player.inventory.add("bracelet_mould") + player.inventory.add("gold_bar", 3) + player.inventory.add("diamond", 2) + val furnace = objects[Tile(3226, 3256), "furnace_lumbridge"]!! + + player.itemOnObject(furnace, 0, "bracelet_mould") + tick() + + player.interfaceOption("make_mould_slayer", "make_bracelet_option_diamond", "Make X") + player.emit(IntEntered(3)) + tick(6) + assertEquals(1, player.inventory.count("gold_bar")) + assertEquals(1, player.inventory.count("bracelet_mould")) + assertEquals(0, player.inventory.count("diamond")) + assertEquals(2, player.inventory.count("diamond_bracelet")) + assertNotEquals(0.0, player.experience.get(Skill.Crafting)) + assertTrue(player.containsMessage("You need some diamond in order to make a diamond bracelet.")) + } + + @Test + fun `Make X more than has resources for`() { + val player = createPlayer("Crafter", Tile(3227, 3255)) + player.levels.set(Skill.Crafting, 99) + player.inventory.add("amulet_unstrung_mould") + player.inventory.add("gold_bar", 1) + player.inventory.add("dragonstone", 2) + val furnace = objects[Tile(3226, 3256), "furnace_lumbridge"]!! + + player.itemOnObject(furnace, 0, "amulet_unstrung_mould") + tick() + + player.interfaceOption("make_mould_slayer", "make_amulet_unstrung_option_dragonstone", "Make X") + player.emit(IntEntered(3)) + tick(6) + assertEquals(0, player.inventory.count("gold_bar")) + assertEquals(1, player.inventory.count("amulet_unstrung_mould")) + assertEquals(1, player.inventory.count("dragonstone")) + assertEquals(1, player.inventory.count("dragonstone_amulet_unstrung")) + assertNotEquals(0.0, player.experience.get(Skill.Crafting)) + assertTrue(player.containsMessage("You need some gold bars in order to make a dragonstone amulet unstrung.")) + } + + @Test + fun `Can't make without correct crafting level`() { + val player = createPlayer("Crafter", Tile(3227, 3255)) + player.levels.set(Skill.Crafting, 65) + player.inventory.add("ring_mould", "gold_bar", "onyx") + val furnace = objects[Tile(3226, 3256), "furnace_lumbridge"]!! + + player.itemOnObject(furnace, 0, "ring_mould") + tick() + + player.interfaceOption("make_mould_slayer", "make_ring_option_onyx", "Make 1") + tick(3) + + assertEquals(1, player.inventory.count("gold_bar")) + assertEquals(1, player.inventory.count("ring_mould")) + assertEquals(1, player.inventory.count("onyx")) + assertEquals(0, player.inventory.count("onyx_ring")) + assertEquals(0.0, player.experience.get(Skill.Crafting)) + assertTrue(player.containsMessage("You need to have a Crafting level of 67")) + } +} \ No newline at end of file diff --git a/game/src/test/kotlin/content/skill/magic/CelestialSurgeBoxTest.kt b/game/src/test/kotlin/content/skill/magic/CelestialSurgeBoxTest.kt index c0bab59f76..59f5698dcd 100644 --- a/game/src/test/kotlin/content/skill/magic/CelestialSurgeBoxTest.kt +++ b/game/src/test/kotlin/content/skill/magic/CelestialSurgeBoxTest.kt @@ -4,7 +4,7 @@ import world.gregs.voidps.engine.entity.item.Item class CelestialSurgeBoxTest : DungeoneeringBoxTest() { override val spell: String = "surge" - override val runes = listOf(Item("air_rune", 7), Item("blood_rune", 1), Item("death_rune", 1)) + override val runes = listOf(Item("air_rune", 7), Item("blood_rune"), Item("death_rune")) override val box: String = "celestial_surgebox" override val mode: Boolean = true } \ No newline at end of file diff --git a/game/src/test/kotlin/content/skill/magic/CelestialWaveBoxTest.kt b/game/src/test/kotlin/content/skill/magic/CelestialWaveBoxTest.kt index 4f650a741f..3f95c5f771 100644 --- a/game/src/test/kotlin/content/skill/magic/CelestialWaveBoxTest.kt +++ b/game/src/test/kotlin/content/skill/magic/CelestialWaveBoxTest.kt @@ -4,7 +4,7 @@ import world.gregs.voidps.engine.entity.item.Item class CelestialWaveBoxTest : DungeoneeringBoxTest() { override val spell: String = "wave" - override val runes = listOf(Item("air_rune", 5), Item("blood_rune", 1)) + override val runes = listOf(Item("air_rune", 5), Item("blood_rune")) override val box: String = "celestial_surgebox" override val mode: Boolean = false } \ No newline at end of file diff --git a/game/src/test/kotlin/content/skill/magic/MagicalBlastBoxTest.kt b/game/src/test/kotlin/content/skill/magic/MagicalBlastBoxTest.kt index 81ccc739ee..fca239075f 100644 --- a/game/src/test/kotlin/content/skill/magic/MagicalBlastBoxTest.kt +++ b/game/src/test/kotlin/content/skill/magic/MagicalBlastBoxTest.kt @@ -4,7 +4,7 @@ import world.gregs.voidps.engine.entity.item.Item class MagicalBlastBoxTest : DungeoneeringBoxTest() { override val spell: String = "blast" - override val runes = listOf(Item("air_rune", 3), Item("death_rune", 1)) + override val runes = listOf(Item("air_rune", 3), Item("death_rune")) override val box: String = "magical_blastbox" override val mode: Boolean = true } \ No newline at end of file diff --git a/game/src/test/kotlin/content/skill/magic/MagicalBoltBoxTest.kt b/game/src/test/kotlin/content/skill/magic/MagicalBoltBoxTest.kt index f7174fbf9b..b740e88ac7 100644 --- a/game/src/test/kotlin/content/skill/magic/MagicalBoltBoxTest.kt +++ b/game/src/test/kotlin/content/skill/magic/MagicalBoltBoxTest.kt @@ -4,7 +4,7 @@ import world.gregs.voidps.engine.entity.item.Item class MagicalBoltBoxTest : DungeoneeringBoxTest() { override val spell: String = "bolt" - override val runes = listOf(Item("air_rune", 2), Item("chaos_rune", 1)) + override val runes = listOf(Item("air_rune", 2), Item("chaos_rune")) override val box: String = "magical_blastbox" override val mode: Boolean = false } \ No newline at end of file diff --git a/game/src/test/kotlin/content/skill/magic/spell/CombinationRuneTest.kt b/game/src/test/kotlin/content/skill/magic/spell/CombinationRuneTest.kt index 40c2c0e874..353595e3c5 100644 --- a/game/src/test/kotlin/content/skill/magic/spell/CombinationRuneTest.kt +++ b/game/src/test/kotlin/content/skill/magic/spell/CombinationRuneTest.kt @@ -23,7 +23,7 @@ class CombinationRuneTest : MagicSpellTest() { dynamicTest("Remove ${combo.replace("_", " ")}s") { Settings.load(mapOf("world.members" to "true")) val player = player() - setItems(Item(element1, 2), Item(element2, 1), Item("chaos_rune", 1)) + setItems(Item(element1, 2), Item(element2), Item("chaos_rune")) player.inventory.add(combo, 10) player.inventory.add("chaos_rune", 10) diff --git a/game/src/test/kotlin/content/skill/magic/spell/DungeoneeringSpellTest.kt b/game/src/test/kotlin/content/skill/magic/spell/DungeoneeringSpellTest.kt index 49267876d2..f21da2a82f 100644 --- a/game/src/test/kotlin/content/skill/magic/spell/DungeoneeringSpellTest.kt +++ b/game/src/test/kotlin/content/skill/magic/spell/DungeoneeringSpellTest.kt @@ -31,7 +31,7 @@ class DungeoneeringSpellTest : MagicSpellTest() { fun `Remove blast box charges`(bolt: Boolean) { val player = player() val catalyst = if (bolt) "chaos_rune" else "death_rune" - setItems(Item("fire_rune", 1), Item("air_rune", 1), Item(catalyst, 1)) + setItems(Item("fire_rune"), Item("air_rune"), Item(catalyst)) addItemDef(ItemDefinition(stringId = "magical_blastbox_bound", extras = mapOf("charges_max" to 1234, "charges" to 10))) player.inventory.add("air_rune", 10) @@ -50,7 +50,7 @@ class DungeoneeringSpellTest : MagicSpellTest() { @Test fun `Remove surge box wave charges`() { val player = player() - setItems(Item("earth_rune", 4), Item("air_rune", 1), Item("blood_rune", 1)) + setItems(Item("earth_rune", 4), Item("air_rune"), Item("blood_rune")) addItemDef(ItemDefinition(stringId = "celestial_surgebox", extras = mapOf("charges_max" to 1234, "charges" to 10))) player.inventory.add("air_rune", 10) @@ -70,9 +70,9 @@ class DungeoneeringSpellTest : MagicSpellTest() { fun `Remove surge box surge charges`() { val player = player() setItems(Item("earth_rune", 4), - Item("air_rune", 1), - Item("death_rune", 1), - Item("blood_rune", 1)) + Item("air_rune"), + Item("death_rune"), + Item("blood_rune")) addItemDef(ItemDefinition(stringId = "celestial_surgebox", extras = mapOf("charges_max" to 1234, "charges" to 10))) player.inventory.add("air_rune", 10) @@ -94,7 +94,7 @@ class DungeoneeringSpellTest : MagicSpellTest() { @ValueSource(strings = [ "magic_blastbox", "celestial_surgebox"]) fun `Dungeoneering box charges don't count towards other spells`(box: String) { val player = player() - setItems(Item("air_rune", 1), Item("chaos_rune", 1)) + setItems(Item("air_rune"), Item("chaos_rune")) addItemDef(ItemDefinition(stringId = box, extras = mapOf("charges_max" to 1234, "charges" to 10))) player.inventory.add("air_rune", 10) @@ -113,7 +113,7 @@ class DungeoneeringSpellTest : MagicSpellTest() { fun `Can't cast without dungeoneering box charges`(spell: String) { val player = player() val box = if (spell.endsWith("bolt") || spell.endsWith("blast")) "magic_blastbox" else "celestial_surgebox" - setItems(Item("air_rune", 1), Item("chaos_rune", 1)) + setItems(Item("air_rune"), Item("chaos_rune")) addItemDef(ItemDefinition(stringId = box, extras = mapOf("charges_max" to 1234, "charges" to 0))) player.equipment.set(EquipSlot.Shield.index, box, 0) @@ -133,7 +133,7 @@ class DungeoneeringSpellTest : MagicSpellTest() { "spell_wave" -> "blood_rune" else -> "death_rune" } - setItems(Item("air_rune", 1), Item(catalytic, 1)) + setItems(Item("air_rune"), Item(catalytic)) addItemDef(ItemDefinition(stringId = box, extras = mapOf("charges_max" to 1234, "charges" to 2))) player.equipment.set(EquipSlot.Shield.index, box, 2) @@ -148,7 +148,7 @@ class DungeoneeringSpellTest : MagicSpellTest() { @ValueSource(strings = ["law", "nature"]) fun `Dungeoneering staff without charges uses runes`(type: String) { val player = player() - setItems(Item("air_rune", 2), Item("${type}_rune", 1)) + setItems(Item("air_rune", 2), Item("${type}_rune")) addItemDef(ItemDefinition(stringId = "${type}_staff", extras = mapOf("charges_max" to 0))) player.inventory.add("air_rune", 10) @@ -164,7 +164,7 @@ class DungeoneeringSpellTest : MagicSpellTest() { @ValueSource(strings = ["law", "nature"]) fun `Dungeoneering staff uses charges not runes`(type: String) { val player = player() - setItems(Item("air_rune", 1), Item("${type}_rune", 2)) + setItems(Item("air_rune"), Item("${type}_rune", 2)) addItemDef(ItemDefinition(stringId = "${type}_staff", extras = mapOf("charges_max" to 10, "charges" to 0))) player.inventory.add("air_rune", 10) @@ -181,7 +181,7 @@ class DungeoneeringSpellTest : MagicSpellTest() { @ValueSource(strings = ["law", "nature"]) fun `Dungeoneering staff in inventory uses runes`(type: String) { val player = player() - setItems(Item("air_rune", 1), Item("${type}_rune", 2)) + setItems(Item("air_rune"), Item("${type}_rune", 2)) addItemDef(ItemDefinition(stringId = "${type}_staff", extras = mapOf("charges_max" to 10, "charges" to 0))) player.inventory.add("air_rune", 10) @@ -201,7 +201,7 @@ class DungeoneeringSpellTest : MagicSpellTest() { override fun nextInt(from: Int, until: Int) = 0 }) val player = player() - setItems(Item("${type}_rune", 1)) + setItems(Item("${type}_rune")) addItemDef(ItemDefinition(stringId = "${type}_staff", extras = mapOf("charges_max" to 10, "charges" to 0))) player.equipment.set(EquipSlot.Weapon.index, "${type}_staff", 10) diff --git a/game/src/test/kotlin/content/skill/magic/spell/MinigameSpellTest.kt b/game/src/test/kotlin/content/skill/magic/spell/MinigameSpellTest.kt index 119005e99d..cf0fd97f5d 100644 --- a/game/src/test/kotlin/content/skill/magic/spell/MinigameSpellTest.kt +++ b/game/src/test/kotlin/content/skill/magic/spell/MinigameSpellTest.kt @@ -11,7 +11,7 @@ class MinigameSpellTest : MagicSpellTest() { @Test fun `Remove minigame runes`() { val player = player() - setItems(Item("earth_rune", 2), Item("air_rune", 1), Item("death_rune", 1)) + setItems(Item("earth_rune", 2), Item("air_rune"), Item("death_rune")) player["minigame_type"] = "fist_of_guthix" player.inventory.add("elemental_rune", 10) @@ -25,11 +25,11 @@ class MinigameSpellTest : MagicSpellTest() { @Test fun `Remove last minigame runes`() { val player = player() - setItems(Item("earth_rune", 1), Item("air_rune", 2), Item("death_rune", 1)) + setItems(Item("earth_rune"), Item("air_rune", 2), Item("death_rune")) player["minigame_type"] = "stealing_creation" player.inventory.add("elemental_rune", 3) - player.inventory.add("catalytic_rune", 1) + player.inventory.add("catalytic_rune") assertTrue(player.removeSpellItems("spell")) assertEquals(0, player.inventory.count("elemental_rune")) @@ -39,7 +39,7 @@ class MinigameSpellTest : MagicSpellTest() { @Test fun `Can't use minigame runes outside of minigame`() { val player = player() - setItems(Item("earth_rune", 1), Item("air_rune", 2), Item("death_rune", 1)) + setItems(Item("earth_rune"), Item("air_rune", 2), Item("death_rune")) player.inventory.add("elemental_rune", 10) player.inventory.add("catalytic_rune", 10) @@ -52,11 +52,11 @@ class MinigameSpellTest : MagicSpellTest() { @Test fun `Not enough minigame runes`() { val player = player() - setItems(Item("air_rune", 3), Item("death_rune", 1)) + setItems(Item("air_rune", 3), Item("death_rune")) player["minigame_type"] = "barbarian_assault" player.inventory.add("elemental_rune", 2) - player.inventory.add("catalytic_rune", 1) + player.inventory.add("catalytic_rune") assertFalse(player.removeSpellItems("spell")) assertEquals(2, player.inventory.count("elemental_rune")) diff --git a/game/src/test/kotlin/content/skill/magic/spell/SpellTest.kt b/game/src/test/kotlin/content/skill/magic/spell/SpellRunesTest.kt similarity index 90% rename from game/src/test/kotlin/content/skill/magic/spell/SpellTest.kt rename to game/src/test/kotlin/content/skill/magic/spell/SpellRunesTest.kt index 432696e9e8..4f3afd2949 100644 --- a/game/src/test/kotlin/content/skill/magic/spell/SpellTest.kt +++ b/game/src/test/kotlin/content/skill/magic/spell/SpellRunesTest.kt @@ -16,14 +16,14 @@ import world.gregs.voidps.engine.inv.inventory import world.gregs.voidps.network.login.protocol.visual.update.player.EquipSlot import set -class SpellTest : MagicSpellTest() { +class SpellRunesTest : MagicSpellTest() { @Test fun `Spell with elemental runes`() { val player = player() player.levels.set(Skill.Magic, 10) setLevel(10) - setItems(Item("air_rune", 1)) + setItems(Item("air_rune")) assertFalse(player.hasSpellItems("spell", message = false)) player.inventory.add("air_rune") @@ -50,7 +50,7 @@ class SpellTest : MagicSpellTest() { World.start() val player = player() - setItems(Item("blood_rune", 1) to ItemDefinition(stringId = "blood_rune", members = true)) + setItems(Item("blood_rune") to ItemDefinition(stringId = "blood_rune", members = true)) player.inventory.add("blood_rune", 10) assertFalse(player.hasSpellItems("spell", message = false)) @@ -63,7 +63,7 @@ class SpellTest : MagicSpellTest() { val player = player() player.levels.set(Skill.Magic, 5) setLevel(10) - setItems(Item("air_rune", 1)) + setItems(Item("air_rune")) player.inventory.add("air_rune") assertFalse(player.hasSpellItems("spell", message = false)) @@ -86,7 +86,7 @@ class SpellTest : MagicSpellTest() { @Test fun `Spell with mix of runes`() { val player = player() - setItems(Item("air_rune", 1), Item("fire_rune", 1), Item("mind_rune", 1)) + setItems(Item("air_rune"), Item("fire_rune"), Item("mind_rune")) player.inventory.add("air_rune") player.inventory.add("fire_rune") @@ -100,7 +100,7 @@ class SpellTest : MagicSpellTest() { @Test fun `Spell with required staff`() { val player = player() - setItems(Item("air_rune", 1), Item("slayers_staff", 1)) + setItems(Item("air_rune"), Item("slayers_staff")) player.inventory.add("air_rune") assertFalse(player.hasSpellItems("spell", message = false)) @@ -114,7 +114,7 @@ class SpellTest : MagicSpellTest() { @Test fun `Spell with required staff not equipped`() { val player = player() - setItems(Item("air_rune", 1), Item("slayers_staff", 1)) + setItems(Item("air_rune"), Item("slayers_staff")) player.inventory.add("air_rune") player.inventory.add("slayers_staff") @@ -127,7 +127,7 @@ class SpellTest : MagicSpellTest() { @Test fun `Staff with infinite runes`() { val player = player() - setItems(Item("air_rune", 1), Item("chaos_rune", 1)) + setItems(Item("air_rune"), Item("chaos_rune")) addItemDef(ItemDefinition(stringId = "staff_of_air", extras = mapOf("infinite_air_runes" to 1))) player.inventory.add("air_rune", 10) @@ -150,7 +150,7 @@ class SpellTest : MagicSpellTest() { "zuriels_staff_corrupted" -> "zuriels_staff" else -> staff } - setItems(Item(required, 1), Item("air_rune", 2)) + setItems(Item(required), Item("air_rune", 2)) player.inventory.add("air_rune", 10) player.equipment.set(EquipSlot.Weapon.index, staff) diff --git a/game/src/test/kotlin/content/skill/smithing/SmeltingTest.kt b/game/src/test/kotlin/content/skill/smithing/SmeltingTest.kt new file mode 100644 index 0000000000..f4412eba5a --- /dev/null +++ b/game/src/test/kotlin/content/skill/smithing/SmeltingTest.kt @@ -0,0 +1,160 @@ +package content.skill.smithing + +import FakeRandom +import WorldTest +import net.pearx.kasechange.toSentenceCase +import objectOption +import org.junit.jupiter.api.Assertions.assertNotEquals +import org.junit.jupiter.api.DynamicTest.dynamicTest +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.TestFactory +import skillCreation +import world.gregs.voidps.engine.entity.character.player.skill.Skill +import world.gregs.voidps.engine.entity.item.Item +import world.gregs.voidps.engine.inv.add +import world.gregs.voidps.engine.inv.equipment +import world.gregs.voidps.engine.inv.inventory +import world.gregs.voidps.network.login.protocol.visual.update.player.EquipSlot +import world.gregs.voidps.type.Tile +import kotlin.test.assertEquals + +class SmeltingTest : WorldTest() { + + private val bars = mapOf( + "bronze" to listOf(Item("copper_ore"), Item("tin_ore")), + "blurite" to listOf(Item("blurite_ore")), + "iron" to listOf(Item("iron_ore")), + "silver" to listOf(Item("silver_ore")), + "steel" to listOf(Item("iron_ore"), Item("coal", 2)), + "gold" to listOf(Item("gold_ore")), + "mithril" to listOf(Item("mithril_ore"), Item("coal", 4)), + "adamant" to listOf(Item("adamantite_ore"), Item("coal", 6)), + "rune" to listOf(Item("runite_ore"), Item("coal", 8)), + ) + + @TestFactory + fun `Smelt bars`() = bars.map { (type, ores) -> + dynamicTest("Smelt $type bar") { + val player = createPlayer("Smelter", Tile(3227, 3255)) + player.levels.set(Skill.Smithing, 99) + player.inventory.add(ores) + val furnace = objects[Tile(3226, 3256), "furnace_lumbridge"]!! + + player.objectOption(furnace, "Smelt") + tick() + + player.skillCreation("${type.toSentenceCase()} bar", 1) + tick(4) + + for (ore in ores) { + assertEquals(0, player.inventory.count(ore.id)) + } + assertEquals(1, player.inventory.count("${type}_bar")) + assertNotEquals(0.0, player.experience.get(Skill.Smithing)) + } + } + + @Test + fun `Smelt more than has resources for`() { + val player = createPlayer("Smelter", Tile(3227, 3255)) + player.levels.set(Skill.Smithing, 99) + player.inventory.add("iron_ore", 2) + player.inventory.add("coal", 3) + val furnace = objects[Tile(3226, 3256), "furnace_lumbridge"]!! + + player.objectOption(furnace, "Smelt") + tick() + + player.skillCreation("Steel bar", 2) + tick(8) + + assertEquals(1, player.inventory.count("iron_ore")) + assertEquals(1, player.inventory.count("coal")) + assertEquals(1, player.inventory.count("steel_bar")) + assertNotEquals(0.0, player.experience.get(Skill.Smithing)) + } + + @Test + fun `Smelt more than one bar`() { + val player = createPlayer("Smelter", Tile(3227, 3255)) + player.levels.set(Skill.Smithing, 99) + player.inventory.add("iron_ore", 2) + val furnace = objects[Tile(3226, 3256), "furnace_lumbridge"]!! + + player.objectOption(furnace, "Smelt") + tick() + + player.skillCreation("Iron bar", 2) + tick(9) + + assertEquals(0, player.inventory.count("iron_ore")) + assertEquals(2, player.inventory.count("iron_bar")) + assertNotEquals(0.0, player.experience.get(Skill.Smithing)) + } + + @Test + fun `Goldsmith gauntlets give bonus xp`() { + val player = createPlayer("Smelter", Tile(3109, 3502)) + player.equipment.set(EquipSlot.Hands.index, "goldsmith_gauntlets") + player.levels.set(Skill.Smithing, 99) + player.inventory.add("gold_ore") + val furnace = objects[Tile(3110, 3502), "furnace_edgeville"]!! + + player.objectOption(furnace, "Smelt") + tick() + + player.skillCreation("Gold bar", 2) + tick(4) + + assertEquals(0, player.inventory.count("gold_ore")) + assertEquals(1, player.inventory.count("gold_bar")) + assertEquals(56.2, player.experience.get(Skill.Smithing)) + } + + @TestFactory + fun `Smelt multiple bars at once with varrock armour`() = bars.toMutableMap().apply { + remove("blurite") + remove("silver") + remove("gold") + }.map { (type, ores) -> + dynamicTest("Smelt multiple $type bars at once") { + val player = createPlayer("Smelter", Tile(3109, 3502)) + player.equipment.set(EquipSlot.Chest.index, "varrock_armour_4") + player.levels.set(Skill.Smithing, 99) + player.inventory.add(ores) + player.inventory.add(ores) + val furnace = objects[Tile(3110, 3502), "furnace_edgeville"]!! + + player.objectOption(furnace, "Smelt") + tick() + + player.skillCreation("${type.toSentenceCase()} bar", 2) + tick(4) + + for (ore in ores) { + assertEquals(0, player.inventory.count(ore.id)) + } + assertEquals(2, player.inventory.count("${type}_bar")) + assertNotEquals(0.0, player.experience.get(Skill.Smithing)) + } + } + + @Test + fun `Don't smelt multiple bars if reached limit`() { + val player = createPlayer("Smelter", Tile(3109, 3502)) + player.equipment.set(EquipSlot.Chest.index, "varrock_armour_4") + player.levels.set(Skill.Smithing, 99) + player.inventory.add("iron_ore", 2) + val furnace = objects[Tile(3110, 3502), "furnace_edgeville"]!! + + player.objectOption(furnace, "Smelt") + tick() + + player.skillCreation("Iron bar", 1) + tick(4) + + assertEquals(1, player.inventory.count("iron_ore")) + assertEquals(1, player.inventory.count("iron_bar")) + assertEquals(12.5, player.experience.get(Skill.Smithing)) + } +} \ No newline at end of file diff --git a/game/src/test/kotlin/content/social/trade/LendTest.kt b/game/src/test/kotlin/content/social/trade/LendTest.kt index 533e7917df..4bd9cbd47b 100644 --- a/game/src/test/kotlin/content/social/trade/LendTest.kt +++ b/game/src/test/kotlin/content/social/trade/LendTest.kt @@ -25,19 +25,19 @@ internal class LendTest : WorldTest() { @Test fun `Lend whip from one player to another`() { val (lender, borrower) = setupTradeWithLend() - val whip = Item("abyssal_whip", 1) + val whip = Item("abyssal_whip") lender.interfaceOption("trade_side", "offer", "Lend", item = whip, slot = 0) acceptTrade(lender, borrower) assertEquals(Item.EMPTY, lender.inventory[0]) assertEquals(whip, lender.returnedItems[0]) - assertEquals(Item("abyssal_whip_lent", 1), borrower.inventory[0]) + assertEquals(Item("abyssal_whip_lent"), borrower.inventory[0]) } @Test fun `Lending a second item replaces offer`() { val (lender, borrower) = setupTradeWithLend() - val whip = Item("abyssal_whip", 1) - val claws = Item("dragon_claws", 1) + val whip = Item("abyssal_whip") + val claws = Item("dragon_claws") lender.interfaceOption("trade_side", "offer", "Lend", item = whip, slot = 0) lender.inventory.add("dragon_claws") lender.interfaceOption("trade_side", "offer", "Lend", item = claws, slot = 0) @@ -45,7 +45,7 @@ internal class LendTest : WorldTest() { assertEquals(whip, lender.inventory[0]) assertEquals(Item.EMPTY, lender.inventory[1]) assertEquals(claws, lender.returnedItems[0]) - assertEquals(Item("dragon_claws_lent", 1), borrower.inventory[0]) + assertEquals(Item("dragon_claws_lent"), borrower.inventory[0]) } @Test @@ -161,7 +161,7 @@ internal class LendTest : WorldTest() { @Test fun `Lent items can be force collected before logout`() { val (lender, borrower) = setupTradeWithLend() - val item = Item("abyssal_whip", 1) + val item = Item("abyssal_whip") lender.interfaceOption("trade_side", "offer", "Lend", item = item, slot = 0) acceptTrade(lender, borrower) borrower.levels.set(Skill.Attack, 75) @@ -178,7 +178,7 @@ internal class LendTest : WorldTest() { @Test fun `Lent items can't be collected before timeout`() { val (lender, borrower) = setupTradeWithLend() - val item = Item("abyssal_whip", 1) + val item = Item("abyssal_whip") lender.interfaceOption("trade_side", "offer", "Lend", item = item, slot = 0) lender.interfaceOption("trade_main", "loan_time", option = "Specify") lender.emit(IntEntered(1)) @@ -195,7 +195,7 @@ internal class LendTest : WorldTest() { @Test fun `Lent items can be collected after logout`() { val (lender, borrower) = setupTradeWithLend() - val item = Item("abyssal_whip", 1) + val item = Item("abyssal_whip") lender.interfaceOption("trade_side", "offer", "Lend", item = item, slot = 0) acceptTrade(lender, borrower) logout(borrower) @@ -210,7 +210,7 @@ internal class LendTest : WorldTest() { @Test fun `Lent items can be collected after timeout`() { val (lender, borrower) = setupTradeWithLend() - val item = Item("abyssal_whip", 1) + val item = Item("abyssal_whip") lender.interfaceOption("trade_side", "offer", "Lend", item = item, slot = 0) lender.interfaceOption("trade_main", "loan_time", option = "Specify") lender.emit(IntEntered(1)) @@ -248,7 +248,7 @@ internal class LendTest : WorldTest() { private fun setupTradeWithLend(): Pair { val lender = createPlayer("lender", emptyTile) val borrower = createPlayer("borrower", emptyTile.addY(1)) - lender.inventory.add("abyssal_whip", 1) + lender.inventory.add("abyssal_whip") lender.playerOption(borrower, "Trade with") borrower.playerOption(lender, "Trade with") tick()