From 18e976ded94a78d5024857f47038c1cb32d59728 Mon Sep 17 00:00:00 2001 From: phobos2077 Date: Fri, 24 May 2024 02:36:00 +0200 Subject: [PATCH] Healing skills implementation in SSL, v2 - Got rid of duplicate code with one function instead of switch/case, while keeping logic (hopefully) unchanged --- .../gl_healing_skill_mod.int | Bin 8428 -> 6306 bytes .../gl_healing_skill_mod.ssl | 382 ++++++------------ 2 files changed, 124 insertions(+), 258 deletions(-) diff --git a/artifacts/example_mods/FirstAidDoctorRepairMod/gl_healing_skill_mod.int b/artifacts/example_mods/FirstAidDoctorRepairMod/gl_healing_skill_mod.int index 40842e2028d54de8562800295f6f5ef4659c3716..2065c1c9627c2a0a4fcb325817f71d7674c9eaa0 100644 GIT binary patch literal 6306 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 literal 8428 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 diff --git a/artifacts/example_mods/FirstAidDoctorRepairMod/gl_healing_skill_mod.ssl b/artifacts/example_mods/FirstAidDoctorRepairMod/gl_healing_skill_mod.ssl index fd02bb99..e2e065df 100644 --- a/artifacts/example_mods/FirstAidDoctorRepairMod/gl_healing_skill_mod.ssl +++ b/artifacts/example_mods/FirstAidDoctorRepairMod/gl_healing_skill_mod.ssl @@ -1,5 +1,6 @@ /* This script reimplements the healing skills of the original game. + This version uses a refactored code with no less code duplication, but potentially some minor differences from vanilla. You can use this to make any tweaks you want to these skills. */ @@ -20,8 +21,7 @@ #define critter_max_hp(cr) get_critter_stat(cr, STAT_max_hit_points) #define critter_cur_hp(cr) get_critter_stat(cr, STAT_current_hp) #define critter_body_type(cr) proto_data(obj_pid(cr), cr_body_type) -#define critter_dmg_flags(cr) get_object_data(cr, OBJ_DATA_DAMAGE_FLAGS) -#define critter_combat_flags(cr) get_object_data(cr, OBJ_DATA_COMBAT_STATE) +#define critter_has_dmg_flag(cr, flag) ((get_object_data(cr, OBJ_DATA_DAMAGE_FLAGS) bwand flag) != 0) #define clear_critter_flag(cr, offset, flag) set_object_data(cr, offset, get_object_data(cr, offset) bwand bwnot(flag)) #define clear_critter_dmg_flag(cr, flag) clear_critter_flag(cr, OBJ_DATA_DAMAGE_FLAGS, flag) @@ -35,6 +35,11 @@ variable times_skill_used, healable_damage_flags; procedure skill_use_slot_available(variable skill) begin variable slot, time, hoursSinceLastUsage, skillOffset := skill * SKILLS_MAX_USES_PER_DAY; + + // Lazy init array + if (not times_skill_used) then + times_skill_used := create_array_list(SKILL_COUNT * SKILLS_MAX_USES_PER_DAY); + for (slot := 0; slot < SKILLS_MAX_USES_PER_DAY; slot++) begin if (times_skill_used[skillOffset + slot] == 0) then return slot; @@ -87,7 +92,7 @@ procedure critter_is_crippled(variable critter) begin if (obj_type(critter) != OBJ_TYPE_CRITTER) then return false; - return (critter_dmg_flags(critter) bwand DAM_CRIP) != 0; + return critter_has_dmg_flag(critter, DAM_CRIP); end procedure get_skill_xp(variable skill) begin @@ -99,7 +104,7 @@ procedure get_skill_xp(variable skill) begin end end -procedure show_skill_use_messages(variable skill, variable successCount) begin +procedure show_skill_use_messages(variable skill, variable successCount := 1) begin variable baseExp, xpToAdd, before, after; if (successCount <= 0) then return; @@ -132,270 +137,139 @@ end /** - * A partial implementation of skill_use function from the engine, with only healing-related code. Returns true if skill use was successful. - * @arg {ObjectPtr} user - Critter using the skill - * @arg {ObjectPtr} target - Skill use target - * @arg {int} skill - Skill num being used - * @arg {int} skillBonus - Skill bonus/modifier from an item being used, such as First Aid Kit - * @ret {bool} + * A refactored version of skill_use function from the engine, for use with healing skills only. Returns true if skill use was successful. + * @arg {ObjectPtr} user + * @arg {ObjectPtr} target + * @arg {int} skill - First Aid, Doctor or Repair + * @arg {int} skillBonus */ -procedure healing_skill_use_impl(variable user, variable target, variable skill, variable skillBonus) begin - variable giveExp, curHp, maxHp, hpToHeal, minHpToHeal, maxHpToHeal, critChance, healingAttempts, successCount, skillUseSlotAdded, roll, i, prefixMsg; +procedure use_healing_skill(variable user, variable target, variable skill, variable skillBonus) begin + variable curHp, maxHp, healingAttempts, isRobot, isRepair, isFirstAid; - //display_msg(string_format("user = %s, target = %s, bonus = %d, skill = %d", obj_name(user), obj_name(target), skillBonus, skill)); - if (user == dude_obj and (skill == SKILL_FIRST_AID or skill == SKILL_DOCTOR)) then begin - variable healerRank := has_trait(TRAIT_PERK, user, PERK_healer); - minHpToHeal := 4 * healerRank; - maxHpToHeal := 10 * healerRank; + display_msg(string_format("use_healing_skill: user = %s, target = %s, bonus = %d, skill = %d", obj_name(user), obj_name(target), skillBonus, skill)); + + isRobot := (critter_body_type(target) == CR_BODY_ROBOTIC); + isRepair := (skill == SKILL_REPAIR); + if (isRepair and not isRobot) then begin + // You cannot repair that. + display_msg(mstr_skill(553)); + return false; + end + if (skill_use_slot_available(skill) == -1) then begin + // 590: You've taxed your ability with that skill. Wait a while. + // 591: You're too tired. + // 592: The strain might kill you. + display_msg(mstr_skill(590 + random(0, 2))); + return false; + end + if (critter_is_dead(target)) then begin + // 512: You can't heal the dead. + // 513: Let the dead rest in peace. + // 514: It's dead, get over it. + display_msg(mstr_skill(512 + random(0, 2))); + return false; end - giveExp := true; + isFirstAid := (skill == SKILL_FIRST_AID); + curHp := critter_cur_hp(target); maxHp := critter_max_hp(target); - critChance := get_critter_stat(user, STAT_crit_chance) + skillBonus; healingAttempts := 1; + if (curHp < maxHp or (not isFirstAid and critter_is_crippled(target))) then begin + variable skillUseSlotAdded, roll, i, prefixMsg, + critChance := get_critter_stat(user, STAT_crit_chance) + skillBonus; - switch (skill) begin - case SKILL_FIRST_AID: begin - if (skill_use_slot_available(SKILL_FIRST_AID) == -1) then begin - // 590: You've taxed your ability with that skill. Wait a while. - // 591: You're too tired. - // 592: The strain might kill you. - display_msg(mstr_skill(590 + random(0, 2))); - return false; - end - if (critter_is_dead(target)) then begin - // 512: You can't heal the dead. - // 513: Let the dead rest in peace. - // 514: It's dead, get over it. - display_msg(mstr_skill(512 + random(0, 2))); - return false; - end - if (curHp < maxHp) then begin - fade_out; + fade_out; - roll := roll_vs_skill(user, skill, critChance) - if (critter_body_type(target) != CR_BODY_ROBOTIC) - else ROLL_FAILURE; + // Heal crippled limbs. + if (not isFirstAid and (not isRepair or not isRobot) and critter_is_crippled(target)) then begin + // Lazy init healable flags + if (not healable_damage_flags) then + healable_damage_flags := array_fixed([ + DAM_BLIND, + DAM_CRIP_ARM_LEFT, + DAM_CRIP_ARM_RIGHT, + DAM_CRIP_LEG_RIGHT, + DAM_CRIP_LEG_LEFT + ]); + for (i := 0; i < len_array(healable_damage_flags); i++) begin + if (not critter_has_dmg_flag(target, healable_damage_flags[i])) then + continue; + + healingAttempts += 1; + roll := roll_vs_skill(user, skill, critChance); if (roll == ROLL_SUCCESS or roll == ROLL_CRITICAL_SUCCESS) then begin - hpToHeal = random(minHpToHeal + 1, maxHpToHeal + 5); - critter_heal(target, hpToHeal); - - if (user == dude_obj) then begin - // You heal %d hit points. - display_msg(sprintf(mstr_skill(500), math_min(maxHp - curHp, hpToHeal))); - end - + clear_critter_dmg_flag(target, healable_damage_flags[i]); clear_critter_combat_flag(target, COMBAT_STATE_FLEEING); - call skill_use_slot_add(SKILL_FIRST_AID); - - // debug skill usage - //display_msg(debug_array_str(array_slice(times_skill_used, skill * SKILLS_MAX_USES_PER_DAY, SKILLS_MAX_USES_PER_DAY))); - successCount := 1; + // 520: You heal your %s. + // 521: You heal the %s. + prefixMsg := 520 if (target == dude_obj) else 521; + call skill_use_slot_add(skill); + skillUseSlotAdded := true; end else begin - // You fail to do any healing. - display_msg(sprintf(mstr_skill(503), how_much(0))); + // 525: You fail to heal your %s. + // 526: You fail to heal the %s. + prefixMsg := 525 if (target == dude_obj) else 526; end - - fade_in; - end else if (user == dude_obj) then begin - // 501: You look healty already - // 502: %s looks healthy already - display_msg(mstr_skill(501) - if (target == dude_obj) - else sprintf(mstr_skill(502), obj_name(target))); + // 530: damaged eye + // 531: crippled left arm + // 532: crippled right arm + // 533: crippled right leg + // 534: crippled left leg + display_msg(sprintf(mstr_skill(prefixMsg), mstr_skill(530 + i))); + if (user == dude_obj) then + call show_skill_use_messages(skill); end + end + + // Restore hit points. + roll := (roll_vs_skill(user, skill, critChance) if isFirstAid else roll_check(has_skill(user, skill), critChance)) + if (isRepair or not isRobot) + else ROLL_FAILURE; + + if (roll == ROLL_SUCCESS or roll == ROLL_CRITICAL_SUCCESS) then begin + variable + minHpToHeal := (1 if isFirstAid else 4), + maxHpToHeal := (5 if isFirstAid else 10), + hpToHeal; + if (user == dude_obj and not isRepair) then begin + variable healerRank := has_trait(TRAIT_PERK, user, PERK_healer); + minHpToHeal += 4 * healerRank; + maxHpToHeal += 10 * healerRank; + end + hpToHeal = random(minHpToHeal, maxHpToHeal); + critter_heal(target, hpToHeal); + if (user == dude_obj) then begin - game_time_advance(30 * ONE_GAME_MINUTE); + // You heal %d hit points. + display_msg(sprintf(mstr_skill(500), math_min(maxHp - curHp, hpToHeal))); end + + if (not skillUseSlotAdded) then + call skill_use_slot_add(skill); + + clear_critter_combat_flag(target, COMBAT_STATE_FLEEING); + if (user == dude_obj) then + call show_skill_use_messages(skill); + end else begin + // You fail to do any healing. + display_msg(sprintf(mstr_skill(503), how_much(0))); end - case SKILL_DOCTOR: begin - if (skill_use_slot_available(SKILL_DOCTOR) == -1) then begin - // 590: You've taxed your ability with that skill. Wait a while. - // 591: You're too tired. - // 592: The strain might kill you. - display_msg(mstr_skill(590 + random(0, 2))); - return false; - end - if (critter_is_dead(target)) then begin - // 512: You can't heal the dead. - // 513: Let the dead rest in peace. - // 514: It's dead, get over it. - display_msg(mstr_skill(512 + random(0, 2))); - return false; - end - if (curHp < maxHp or critter_is_crippled(target)) then begin - fade_out; - if (critter_body_type(target) != CR_BODY_ROBOTIC and critter_is_crippled(target)) then begin - for (i := 0; i < len_array(healable_damage_flags); i++) begin - if ((critter_dmg_flags(target) bwand healable_damage_flags[i]) != 0) then begin - healingAttempts += 1; - roll := roll_vs_skill(user, skill, critChance); - if (roll == ROLL_SUCCESS or roll == ROLL_CRITICAL_SUCCESS) then begin - clear_critter_dmg_flag(target, healable_damage_flags[i]); - clear_critter_combat_flag(target, COMBAT_STATE_FLEEING); - // 520: You heal your %s. - // 521: You heal the %s. - prefixMsg := 520 if (target == dude_obj) else 521; - call skill_use_slot_add(SKILL_DOCTOR); - successCount := 1; - skillUseSlotAdded := true; - end else begin - // 525: You fail to heal your %s. - // 526: You fail to heal the %s. - prefixMsg := 525 if (target == dude_obj) else 526; - end - // 530: damaged eye - // 531: crippled left arm - // 532: crippled right arm - // 533: crippled right leg - // 534: crippled left leg - display_msg(sprintf(mstr_skill(prefixMsg), mstr_skill(530 + i))); - if (user == dude_obj) then - call show_skill_use_messages(skill, successCount); - giveExp := false; - end - end - end - - roll := roll_vs_skill(user, skill, critChance) - if (critter_body_type(target) != CR_BODY_ROBOTIC) - else ROLL_FAILURE; - - if (roll == ROLL_SUCCESS or roll == ROLL_CRITICAL_SUCCESS) then begin - hpToHeal = random(minHpToHeal + 4, maxHpToHeal + 10); - critter_heal(target, hpToHeal); - - if (user == dude_obj) then begin - // You heal %d hit points. - display_msg(sprintf(mstr_skill(500), math_min(maxHp - curHp, hpToHeal))); - end - - if (not skillUseSlotAdded) then - call skill_use_slot_add(SKILL_DOCTOR); - - clear_critter_combat_flag(target, COMBAT_STATE_FLEEING); - successCount := 1; - if (user == dude_obj) then - call show_skill_use_messages(skill, successCount); - giveExp := false; - end else begin - // You fail to do any healing. - display_msg(sprintf(mstr_skill(503), how_much(0))); - end - - fade_in; - end else if (user == dude_obj) then begin - // 501: You look healty already - // 502: %s looks healthy already - display_msg(mstr_skill(501) - if (target == dude_obj) - else sprintf(mstr_skill(502), obj_name(target))); - end - if (user == dude_obj) then begin - game_time_advance(ONE_GAME_HOUR * healingAttempts); - end - end - case SKILL_REPAIR: begin - if (critter_body_type(target) != CR_BODY_ROBOTIC) then begin - // You cannot repair that. - display_msg(mstr_skill(553)); - return false; - end - if (skill_use_slot_available(SKILL_REPAIR) == -1) then begin - // 590: You've taxed your ability with that skill. Wait a while. - // 591: You're too tired. - // 592: The strain might kill you. - display_msg(mstr_skill(590 + random(0, 2))); - return false; - end - if (critter_is_dead(target)) then begin - // You got it? - display_msg(mstr_skill(1101)); - return false; - end - if (curHp < maxHp or critter_is_crippled(target)) then begin - fade_out; - - // Healing of crippled limbs - for (i := 0; i < len_array(healable_damage_flags); i++) begin - if ((critter_dmg_flags(target) bwand healable_damage_flags[i]) != 0) then begin - healingAttempts += 1; - roll := roll_vs_skill(user, skill, critChance); - if (roll == ROLL_SUCCESS or roll == ROLL_CRITICAL_SUCCESS) then begin - clear_critter_dmg_flag(target, healable_damage_flags[i]); - clear_critter_combat_flag(target, COMBAT_STATE_FLEEING); - // 520: You heal your %s. - // 521: You heal the %s. - prefixMsg := 520 if (target == dude_obj) else 521; - call skill_use_slot_add(SKILL_REPAIR); - successCount := 1; - skillUseSlotAdded := true; - end else begin - // 525: You fail to heal your %s. - // 526: You fail to heal the %s. - prefixMsg := 525 if (target == dude_obj) else 526; - end - // 530: damaged eye - // 531: crippled left arm - // 532: crippled right arm - // 533: crippled right leg - // 534: crippled left leg - display_msg(sprintf(mstr_skill(prefixMsg), mstr_skill(530 + i))); - if (user == dude_obj) then - call show_skill_use_messages(skill, successCount); - giveExp := false; - end - end - - // For some reason, original code uses roll_check here, which is lower level function that doesn't take party member's skills into account, unlike roll_vs_skill (which calls into skill_result - roll := roll_check(has_skill(user, skill), critChance); - - if (roll == ROLL_SUCCESS or roll == ROLL_CRITICAL_SUCCESS) then begin - hpToHeal = random(minHpToHeal + 4, maxHpToHeal + 10); - critter_heal(target, hpToHeal); - - if (user == dude_obj) then begin - // You heal %d hit points. - display_msg(sprintf(mstr_skill(500), math_min(maxHp - curHp, hpToHeal))); - end - - if (not skillUseSlotAdded) then - call skill_use_slot_add(SKILL_REPAIR); - - clear_critter_combat_flag(target, COMBAT_STATE_FLEEING); - successCount := 1; - if (user == dude_obj) then - call show_skill_use_messages(skill, successCount); - giveExp := false; - end else begin - // You fail to do any healing. - display_msg(sprintf(mstr_skill(503), how_much(0))); - end - - fade_in; - end else if (user == dude_obj) then begin - // 501: You look healty already - // 502: %s looks healthy already - display_msg(mstr_skill(501) - if (target == dude_obj) - else sprintf(mstr_skill(502), obj_name(target))); - end - if (user == dude_obj) then begin - game_time_advance(ONE_GAME_HOUR * healingAttempts); - end - end - default: begin - debug_msg(mstr_skill(510)); // skill_use: invalid skill used. - return false; - end + fade_in; + end else if (user == dude_obj) then begin + // 501: You look healty already + // 502: %s looks healthy already + display_msg(mstr_skill(501) + if (target == dude_obj) + else sprintf(mstr_skill(502), obj_name(target))); end - if (giveExp and user == dude_obj) then - call show_skill_use_messages(skill, successCount); - - return true; + if (user == dude_obj) then begin + game_time_advance((ONE_GAME_HOUR if (skill == SKILL_DOCTOR) else (30 * ONE_GAME_MINUTE)) * healingAttempts); + end + // TODO: not sure if this is needed + //exec_map_update_scripts end @@ -448,7 +322,7 @@ procedure protinst_use_item_on(variable user, variable target, variable item) be return 0; end - if (not healing_skill_use_impl(user, target, skill, skillBonus)) then + if (not use_healing_skill(user, target, skill, skillBonus)) then return 0; if (random(1, 10) != 1) then @@ -511,7 +385,7 @@ procedure useskill_hook begin isSuccess; if (skill == SKILL_FIRST_AID or skill == SKILL_DOCTOR or skill == SKILL_REPAIR) then begin - isSuccess := healing_skill_use_impl(user, target, skill, skillBonus); + isSuccess := use_healing_skill(user, target, skill, skillBonus); set_sfall_return(0 if isSuccess else 1); end end @@ -521,13 +395,5 @@ procedure start begin if (game_loaded) then begin register_hook_proc(HOOK_USEOBJON, useobjon_hook); register_hook_proc(HOOK_USESKILL, useskill_hook); - times_skill_used := create_array_list(SKILL_COUNT * SKILLS_MAX_USES_PER_DAY); - healable_damage_flags := array_fixed([ - DAM_BLIND, - DAM_CRIP_ARM_LEFT, - DAM_CRIP_ARM_RIGHT, - DAM_CRIP_LEG_RIGHT, - DAM_CRIP_LEG_LEFT - ]); end end