From e00d02f1f0adbe6fa5874e84ef4cd8f23d4d6c93 Mon Sep 17 00:00:00 2001 From: NovaRain Date: Sun, 1 Sep 2019 11:38:34 +0800 Subject: [PATCH] Added a compute damage example script. Updated compiled scripts due to main.h changes. --- .../ComputeDamage/gl_compute_damage.ssl | 206 ++++++++++++++++++ .../gl_highlighting_lite.int | Bin 3648 -> 3668 bytes .../example_mods/ItemHighlight_Lite/main.h | 24 +- 3 files changed, 225 insertions(+), 5 deletions(-) create mode 100644 artifacts/example_mods/ComputeDamage/gl_compute_damage.ssl diff --git a/artifacts/example_mods/ComputeDamage/gl_compute_damage.ssl b/artifacts/example_mods/ComputeDamage/gl_compute_damage.ssl new file mode 100644 index 00000000..44d32934 --- /dev/null +++ b/artifacts/example_mods/ComputeDamage/gl_compute_damage.ssl @@ -0,0 +1,206 @@ +/* + Example algorithm of how the game engine calculates combat damage +*/ + +#include "..\headers\define.h" +#include "..\headers\command.h" +#include "..\headers\sfall\sfall.h" +#include "..\headers\sfall\define_extra.h" + +procedure start; +procedure compute_damage_F2; +procedure item_w_damage_hook; +procedure item_w_subtype(variable weapon, variable hit_mode); +procedure get_ammo_value(variable weapon, variable param); + +variable item_w_damage; + +procedure start begin + if game_loaded then begin + register_hook_proc(HOOK_COMBATDAMAGE, compute_damage_F2); + register_hook_proc(HOOK_ITEMDAMAGE, item_w_damage_hook); + end +end + +procedure compute_damage_F2 begin + variable dmg_type, weapon_perk, dmg_thresh, dmg_resist, weapon_subtype, bonus_ranged, difficulty, i, dmg_mult, dmg_div, damage; + variable target, flags, knockback, amount; + + variable + ctdTarget := get_sfall_arg, + ctdSource := get_sfall_arg, + amountTarget := get_sfall_arg, + amountSource := get_sfall_arg, + flagsTarget := get_sfall_arg, + flagsSource := get_sfall_arg, + weapon := get_sfall_arg, + bodypart := get_sfall_arg, + damageMultiplier := get_sfall_arg, + rounds := get_sfall_arg, + amountKnockback := get_sfall_arg, + hit_mode := get_sfall_arg; + + if (flagsSource bwand DAM_HIT) then begin + target := ctdTarget; + flags := flagsTarget; + knockback := 1; + end else begin + target := ctdSource; + flags := flagsSource; + knockback := 0; + end + + //amount := 0; + if target and (obj_type(target) == OBJ_TYPE_CRITTER) then begin + if weapon then begin + dmg_type := weapon_dmg_type(weapon); + weapon_perk := get_proto_data(obj_pid(weapon), PROTO_WP_PERK); + end else begin + dmg_type := DMG_normal_dam; + weapon_perk := -1; + end + + dmg_thresh := get_critter_stat(target, STAT_dmg_thresh + dmg_type); + dmg_resist := get_critter_stat(target, STAT_dmg_resist + dmg_type); + + if (flags bwand DAM_BYPASS) and (dmg_type != DMG_emp) then begin + dmg_thresh := dmg_thresh * 20 / 100; + dmg_resist := dmg_resist * 20 / 100; + end else begin + if (weapon_perk == PERK_weapon_penetrate) + or (hit_mode == ATKTYPE_PALMSTRIKE or hit_mode == ATKTYPE_PIERCINGSTRIKE + or hit_mode == ATKTYPE_HOOKKICK or hit_mode == ATKTYPE_PIERCINGKICK) then + dmg_thresh := dmg_thresh * 20 / 100; + + if ctdSource == dude_obj and has_trait(TRAIT_TRAIT, ctdSource, TRAIT_finesse) then + dmg_resist += 30; + end + + weapon_subtype := item_w_subtype(weapon, hit_mode); // item_w_subtype_ + if (ctdSource != dude_obj) or (weapon_subtype != WEAPON_TYPE_GUNS) then + bonus_ranged := 0; + else + bonus_ranged := has_trait(TRAIT_PERK, ctdSource, PERK_bonus_ranged_damage) * 2; + + difficulty := 100; + if (has_trait(TRAIT_OBJECT, ctdSource, OBJECT_TEAM_NUM) != has_trait(TRAIT_OBJECT, dude_obj, OBJECT_TEAM_NUM)) then begin + if (combat_difficulty == 0) then + difficulty := 75; + else if (combat_difficulty == 2) then + difficulty := 125; + end + + // F2 default start + // Damage = (1 - (DR_armor + DR_ammo_adjust) * (((raw_damage * (dmg_mult * damageMultiplier)) / dmg_div) - dmg_thresh) + dmg_resist += get_ammo_value(weapon, PROTO_AM_DR_MOD); // item_w_dr_adjust_ (DR Adjust %) + if (dmg_resist < 100) then begin + if (dmg_resist < 0) then dmg_resist := 0; + + dmg_mult := damageMultiplier * get_ammo_value(weapon, PROTO_AM_DMG_MULT); // item_w_dam_mult_ (Dmg mod A) + dmg_div := get_ammo_value(weapon, PROTO_AM_DMG_DIV); // item_w_dam_div_ (Dmg mod B) + + for (i := 1; i <= rounds; i++) begin + damage := (item_w_damage + bonus_ranged) * dmg_mult; // item_w_damage_ (raw_damage) + if dmg_div then damage /= dmg_div; + + damage := (((damage / 2) * difficulty) / 100) - dmg_thresh; + if (damage > 0) then begin + damage := damage - ((damage * dmg_resist) / 100); // reduce damage by the percentage of DR_armor + DR_Ammo + if (damage > 0) then amount += damage; + end + end + end + // F2 default end + + if (ctdSource == dude_obj) then begin + if has_trait(TRAIT_PERK, ctdSource, PERK_living_anatomy_perk) and (critter_kill_type(ctdTarget) != KILL_TYPE_robot_kills) + and (critter_kill_type(ctdTarget) != KILL_TYPE_alien_kills) then + amount += 5; + if has_trait(TRAIT_PERK, ctdSource, PERK_pyromaniac_perk) and (dmg_type == DMG_fire) then + amount += 5; + end + + if knockback and ((get_flags(target) bwand FLAG_MULTIHEX) == 0) + and (dmg_type == DMG_explosion or weapon == 0 or weapon_subtype == WEAPON_TYPE_MELEE) + and ((get_proto_data(obj_pid(target), PROTO_CR_FLAGS) bwand CFLG_NOKNOCKDOWN) == 0) then begin // critter_flag_check_ + damage := 0; + if (target == dude_obj) and has_trait(TRAIT_PERK, target, PERK_stonewall_perk) then begin + damage := 1; + if (random(0, 100) < 50) then knockback := 0; + end + if knockback then begin + if (weapon_perk == PERK_weapon_knockback) then + amountKnockback := amount / 5; + else + amountKnockback := amount / 10; + + if damage then amountKnockback /= 2; + end + end + end + + if (flagsSource bwand DAM_HIT) then begin + display_msg("amountTarget = " + amountTarget+ ", amount = " + amount); + amountTarget := amount; + flagsTarget := flags; + end else begin + display_msg("amountSource = " + amountSource+ ", amount = " + amount); + amountSource := amount; + flagsSource := flags; + end + + set_sfall_return(amountTarget); + set_sfall_return(amountSource); + set_sfall_return(flagsTarget); + set_sfall_return(flagsSource); + set_sfall_return(amountKnockback); +end + +procedure item_w_damage_hook begin + variable + item_w_damage_min := get_sfall_arg, + item_w_damage_max := get_sfall_arg; + //weapon := get_sfall_arg, + //source := get_sfall_arg, + //hit_mode := get_sfall_arg, + //isMelee := get_sfall_arg; + + item_w_damage := (item_w_damage_min + (item_w_damage_max - item_w_damage_min) / 2); + display_msg("item_w_damage_ = " + item_w_damage); + + set_sfall_return(item_w_damage); +end + +procedure item_w_subtype(variable weapon, variable hit_mode) begin + variable attack_mode, type := WEAPON_TYPE_UNARMED; + + if weapon and (hit_mode <= ATKTYPE_RWEP2) then begin + attack_mode := (get_proto_data(obj_pid(weapon), PROTO_IT_FLAGS)); + + if (hit_mode == ATKTYPE_LWEP2) or (hit_mode == ATKTYPE_RWEP2) then + attack_mode := (attack_mode bwand 0xF0) / 16; // shift 4 bits to the right + else + attack_mode := (attack_mode bwand 0x0F); + + if (attack_mode > ATKMODE_PRI_THROW) then + type := WEAPON_TYPE_GUNS; + else if (attack_mode == ATKMODE_PRI_THROW) then + type := WEAPON_TYPE_THROWN; + else if (attack_mode > ATKMODE_PRI_KICK) then + type := WEAPON_TYPE_MELEE; + end + + return type; +end + +procedure get_ammo_value(variable weapon, variable param) begin + variable pid := -1, value := 0; // default DR value + + if weapon then begin + pid := get_weapon_ammo_pid(weapon); + if (pid > -1) then value := get_proto_data(pid, param); + end + if (pid == -1 and param != PROTO_AM_DR_MOD) then value := 1; // default value for Mult/Div + + return value; +end diff --git a/artifacts/example_mods/ItemHighlight_Lite/gl_highlighting_lite.int b/artifacts/example_mods/ItemHighlight_Lite/gl_highlighting_lite.int index 36899a4c118510f7408cb24aa89dfc44b8471287..02b0d7b96878ebb9b22f8ffb6036a99fdc2aed5a 100644 GIT binary patch delta 1482 zcmX>gb45m=f$0Dv0|SFl122eX37RNiSigV)0<<6$jAQ|cvoJ6)*uX>}G^+yx0|PSy z1A_;I4kW&48${XXJtjL1=c6L5vIxj4}{DjN}42 zhJk^BQ4b~pp}D_7Xht^(4I_EHAS^}?1_3=3z`(#DP*RkbSDcerk~!I)kwZqnJ+;I$ zFVi_cFD)}YxTJ`Ify+I$1j5~%$jHaYcxQ3}(@Z&`5SX_7ykfn~yi5iL2CkHpqQr6# zXR|DG38S!A151N8D0mqdz$9~n(PRZy?Ld|WLlB=;4MZ}qG#DLV{Qv*|{|4g*X^;r3 zNP|R!YlD7+6o?0sp8$#~wg%${eXs}&!7aIk;&#>sA(#w1!{l>ps@V{8m>Yzk<`^KE!_Z*Va1v|}BP=Y~ zqhRKNop=r`%g|udR1RVZFf=%TLJGuY?*owxAh+m))!v#M$1cgatbql}YhdqWJTaMz z!&iC*OeI+6MN?UW2_$4WmQC*ARG&PPLxNMT0UQvVk0$TpuxETU`4@+;^dXqOhTl*Y zG{!h*Oitp|WIQmrhtrOSlMia;ucore6WC2Ab8$&Z--Bu}g3>}T4|1hUw&Rjy+%!3Y zOO~-`av7JRU=>&mQ-cx2QQRSuS8!=EI!(UBWymemR0c^F+!mAhxMih%AkJjqY!GVL z0n*1^1QFpb0L!;PcnlnH`Be}R?iC<;@p}*+G=VZT2!qYIGkFuYxi-YDOt7fpk%L54 z;}eh?26j+#1P9=)#wU|I*fmu6Y#LJ_vC5MJQQ9N`R?5;~4)F?4%j5(e@yvD5B)AWx zolym>2AV^_Y$j;pV}v+|=N^iBEwCDF>X{+xdHG=KCkyb3*TYO>fy&y!WWlyO;WUjE zsy+`zy&qUT#9z!{Hq3lBsQNizQMLvlFwHo*j91+L2#OhTU>R&aV27IV4x*kh5A4Q< V$!B<_`6ZxYE5KsACV%7g0suFpGARH6 delta 1364 zcmca2b3jI*f$0Dv0|SFl122eXahoV$SU-gU0<<6$jAQ|cGczzSn88FKG^-E;0|Q9h z4Z??!tQ!~@7?>Cs7=mCT5Sq;jLNk1T(ol-61){#5kpn6MrPx<7FfcGOFfd9%1)vls z)Br{ur~s7Wegt7KxiUF z067}OX0HN~42%s%4f%Mz%uum${I`>^g&`AlO`|VRG++-LxPj5fdwSOd2aGK4tvIPlleG(8P`pY;gn=- znOw%H$+%|n0!}*~j$csYKQxt1HsDd1%*CZ^dJ3cw;5U29YYTyNj z^cE1w2uXAhHIS6V*uV