From 694b3995ef2913ad72e3c7d25fd91745a0f37f32 Mon Sep 17 00:00:00 2001 From: NovaRain Date: Sun, 1 Sep 2019 11:37:04 +0800 Subject: [PATCH] Added a compute damage example script. Updated compiled scripts due to main.h changes. --- .../ComputeDamage/gl_compute_damage.ssl | 206 ++++++++++++++++++ artifacts/mods/gl_highlighting.int | Bin 3964 -> 3984 bytes artifacts/mods/gl_npcarmor.int | Bin 4408 -> 4418 bytes artifacts/mods/gl_partycontrol.int | Bin 4148 -> 4158 bytes artifacts/mods/main.h | 24 +- 5 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/mods/gl_highlighting.int b/artifacts/mods/gl_highlighting.int index df28f02bb2005915aaa0f187b24d34f8a8d367c7..3112fa38a9574867c6fd659c1b05d2cb0ac44bdf 100644 GIT binary patch delta 1585 zcmew(H$h&Yf$0Dv0|SFl122eXSvOI@u>KDN1ZY7h7|8+>XJKGquz`s{Xx2Fl3=GT+ z3=AF+K8$3OVqjokVqjnhfr&t9wj~gn;S-dGQfyx!>gyS~pdwI;17r{*0|TQBQ~*kG zB|sRAdJq~$@&rLxj7|_5M)ItHuo$BtG>qgGgRmHjz_c)!1QEPhAd-QBv1D=(qpFO6 zduoYiUZ!(?URq{)a7hsZ1DAVh352_OBBK=}t*I; zGB7Z3rKA)kmV-E(E163eg|ix18ni({&cFaBnH!8I|6@^&d=2KYG#G+t)+P|iz|vrJ zfbswT|Nk3|8>B%ZtOX4c4XzFP4N@Q;NPYq+64@Gz8}z{9&$6G%95GEF|mVb59B09L_eH(89+p3!b{7^kna9M}qw+kZn@(6HzH zGI<}TCZo*ca~$fE`MD%Gv!GV~nry)3&uBHdflIRf0L1@|>klx3az=v#D7HZ6@bH01 z22e;rVu}&WXKD}z(cCXUBm;YcP=kKMelXj*5u7m@m>?;F`x;o32^16{7WW1a3DNz5wEs#MPmviauJ@yv73l)Mk5mr(_*2I4ekFq^4?6-+ZiB7yfGih3=u95(gL5cPa| zF!hrS_{8gBrm;X}<6yF2+nsQl#tK#6hoasOtRCVoRM)aW)$akTU~3Qp(~Og+@rm0% pK`|o^EQ8Gl><}~f`5@{U^T2LwnEZxMn%@E{wgN1+YqA)B8UVTXJJ|pL delta 1489 zcmbOr|3^-sf$0Dv0|SFl122eXSu|0=u>J!B1ZY7h7|8+>XJ%kvFoTIeXx2Oi1_qG0 z8-x!d*?1Tj7?>Cs7=mCT5Sncogk}Jl2W5gNwg(XP^^6=KE&_9~F)%PNGB7YoA;dr| zE*}udz`&>jp7k<|Ns9D z#tqUS5!MF{5)G~m`VCSb9!P!yD9+d>zhR9Rt^tcNH5fIxLR7P5O^##p)jrU`3s%(v zCVRl-Jg{13Fv--w3Z@wvgeOnnk#k{x2jv<;jA8d^kbqmsh%laA3B@t24MH%B**zxP zv8&`j4PtH(f*MqTWDrAxQNu~FMT{`tu`hxd2zKKUuq;D^QBygHCBV?&0P;JC&3+9; zGJqVT4_13&@;P=1F7|f~EKu$T_D)8D$yFRaG8`XZYQa+Xn#vkX8uUS89PcLo;Z&c@ z$tl5^*1!T1;nJF{#c9u|H93pZSDFhX0=DBflm(3i&Igk(acVMhO#Z`Z&m9J}@Obx;ynnz`F1&=vn&EzN^S;i_5TksV~oPh}zZ#;V@AK+1Cd@;F# z$4rRV4pov@YqB1%IOB!MZoJy{DUB(RsOE)6b&~*CHA{mTB*=LuK#CWr6IdEpAs*!2 z1x=(|K#{}G?6kw9L@U*MZE&p7KVB-g{pxWqJd8eMS~t#B{mCKpz6I) z)LY9 zO_pJkWDJ>X#+K}S0%R%!V}ntH0f@!k0V2WtlVBEegK>jChy|5lX%GVO7#JFi8>B%j zcBaX9*pwL!Cb1hcc1$*5cV|2?xrW`IamnO8?A7W@ASDb84Mq^f90?5)4f+jIU{R2z zU?Vu{CdYBeGOnA%E$uap9hatB>1Iq+ZEIw-t znJmX9=ElVZRt~p=(+!&)oGD16%pjvdi2>$0&PkJ#IJFrMfLySYQ-hIf@;Od1CN7T2 z&o~1)g&OvQEM(-F?7$_q>JXcm8;qJtAWmdpZZK+m3UUv(5W<<0 zxO66Safq0J#Ca58rZttpJjSB{k^u)gBs$=M%RO&$4Yxewoyl{!Wf|{G-o-7?$TvBT zOMNmU&lGO0#uP}X^6Z+tfX9(n2INYHePHt3d_|=7PAd4~F zXwq-eo4kx)e)3a(4aNhL`2>6!7fg;32$z(ABv}R~c#?scaz+4Q%Rd2m=8guINn8>D D79Zod delta 1063 zcmX@4v_natf$0Dv0|SFl122eX=9?&BSZ~Jw0Z|YNMlyrMnHd-u3Sc4-nq>(C0|Q9B z4Z??!Y)K3Z3?Rd2!9*Z5`x6MwumMU#DJ}^JLyO@EgaISD6`-s;P#Q|{=uLd}meFYP z4aS)wB6|8EMTvREIf*5i`FX{9nR%HEllz&rvFbIjG-yv&U>0Ly>6!e1#ms{F0LZ5d zObtd2t_}KNHgki~1dv0IH0d|+Hb^#THE1^QG{}JDSb7>*AoS!5%=U~5lLc7RB`ZK8 z46F@CV49)9xIr4kVu_m^z@pB0WO4;dI-}R*2Q21{7Lz4d4JFSt>4VKLYcd6?V_KGUsj2a9;EcQAO z3Fe;!vzQxGOZAWOjB;3%1#!6D1IWbzD7)ybR|w=rhAm+7$mAb9mW*pA8}T-3Yk<-b$XAfCY0?GLj19sdm5fNb z7*!_Uo6N`8%E&i)3ST2**JLq%c}AAWX8hXhP?eK2_~rQ(z-BN&QZJ*?N-rP7?@c$0|OHS z1A_^K4*~ld)V3qmw@Hi8iX43K`i#J$sz2q zsuMtL1_qE7pdf--!6DHg(V*WT1(Id|G5H$1JfpTLj15LjuJ2`~Il`(GeERJBtbCch3NHW?@=HT=+T++Y-mcQ3j z)*uCDeE{oagt{xIsRGPrZ4idYPHy6KwE@Q{!U!1ar9Uu_~c322- zc_I7(ay3{t)QuoEBhzFLE^Emsh)LX0VBK7>FycBfc@CGlIz$u}Mhp$+kkI88X^?1e zg@qC~&*WEJ>e5jS`$6V1AlbpN4+%1 z#YLkU_BS#dU}R)qSO|+39*4F(vE0Vw3mrOHS_O*Wted69K#K(Bvch1pv`?`+ooc delta 1258 zcmdm|utht(lz1n#uTX@(os9#)!#mY!OVX ze${I`{ z7I371Wk43XHt0iSC&zKPGKNfE!VxTeq^S%n&)i_t@EOcvX)pxQoFb z3%MY&?65%LazJLL24hGF^8_^PZ)7;Y$jHF35EgMfW|LKTrV1KBRT@DO0?)O{ zr+8#}Ss>%YfJn3=Kk1+5+M}J}nfTc9RwO6r+>CYCy38P7{ni&~(7i zU8l$-b;B|QJH(&-Q7Ar{H93G^k-r5+Y~ADr QetZ5)C}KM%pW`n80EOTaGynhq diff --git a/artifacts/mods/main.h b/artifacts/mods/main.h index 84a4c50a..8e09b02d 100644 --- a/artifacts/mods/main.h +++ b/artifacts/mods/main.h @@ -10,21 +10,35 @@ variable ini := "sfall-mods.ini"; variable translationIni; -// Gets the integer value from ini +// Gets the integer value from the specified ini +procedure GetIniConfig(variable section, variable key, variable def, variable inifile) begin + variable val := get_ini_setting(inifile + "|" + section + "|" + key); + if val == -1 then val := def; + return val; +end + +// Gets the string value from the specified ini +procedure GetIniConfigStr(variable section, variable key, variable def, variable inifile) begin + variable val := get_ini_string(inifile + "|" + section + "|" + key); + if val == -1 or val == "" then val := def; + return val; +end + +// Gets the integer value from sfall-mods.ini procedure GetConfig(variable section, variable key, variable def) begin variable val := get_ini_setting(ini + "|" + section + "|" + key); if val == -1 then val := def; return val; end -// Gets the string value from ini +// Gets the string value from sfall-mods.ini procedure GetConfigStr(variable section, variable key, variable def) begin variable val := get_ini_string(ini + "|" + section + "|" + key); if val == -1 or val == "" then val := def; return val; end -// Gets the value from ini as a temp array of strings +// Gets the value from sfall-mods.ini as a temp array of strings procedure GetConfigList(variable section, variable key) begin variable val := get_ini_string(ini + "|" + section + "|" + key); if val == -1 or val == "" then return []; @@ -32,7 +46,7 @@ procedure GetConfigList(variable section, variable key) begin return string_split(val, ","); end -// Gets the value from ini as a temp array of ints +// Gets the value from sfall-mods.ini as a temp array of ints procedure GetConfigListInt(variable section, variable key) begin variable arr, i, item; @@ -53,5 +67,5 @@ procedure Translate(variable id, variable def) begin end procedure InitConfigs begin - translationIni := GetConfigStr("Main", "TranslationsINI", "./Translations.ini"); + translationIni := GetIniConfigStr("Main", "TranslationsINI", "Translations.ini", "ddraw.ini"); end