diff --git a/artifacts/example_mods/NPCArmor/gl_npcarmor.int b/artifacts/example_mods/NPCArmor/gl_npcarmor.int new file mode 100644 index 00000000..d05c5e1d Binary files /dev/null and b/artifacts/example_mods/NPCArmor/gl_npcarmor.int differ diff --git a/artifacts/example_mods/NPCArmor/gl_npcarmor.ssl b/artifacts/example_mods/NPCArmor/gl_npcarmor.ssl new file mode 100644 index 00000000..95e9c385 --- /dev/null +++ b/artifacts/example_mods/NPCArmor/gl_npcarmor.ssl @@ -0,0 +1,222 @@ +/* + + NPC Armor Appearance mod + + Used to replace the scripted part of B-Team mod. + Appropriate graphics are required for this mod to work. + Can be adopted to any mod by adjusting armor PIDs, allowed weapon anim codes, NPC PIDs and NPC FIDs in INI file. + + NOTE: this script requires compiler from sfall modderspack with -s option + (short circuit evaluation) + + version 1.1 + +*/ + +#include "main.h" + +#define IS_ARMOR(item) (obj_type(item) == OBJ_TYPE_ITEM and obj_item_subtype(item) == item_type_armor) +#define IS_WEAPON(item) (obj_type(item) == OBJ_TYPE_ITEM and obj_item_subtype(item) == item_type_weapon) + +#define FID_OBJ_CRITTER (0x01000000) + +procedure update_armor_apperance; + +variable + modIni := "npcarmor.ini", + defaultFids, + armorPidMap, // maps armor PID to it's "type" - leather armor, metal, power armor, etc. + npcMap, + altWeapon, + unWieldWeapon; + +/* + Returns the FID value set in the config settings for party member armor: Jacket, Leather, etc. +*/ +procedure check_armor_change(variable critter, variable armor, variable isWield) begin + variable npc, armorType, fid; + npc := npcMap[obj_pid(critter)]; + if (npc) then begin + if (isWield == false) then begin + // display_msg("No armor fid: " + npc["Default"]); + return npc["Default"]; + end else if (armor) then begin + armorType := armorPidMap[obj_pid(armor)]; + fid := npc[armorType] or defaultFids[armorType]; + if (fid == 0 or fid == -1) then fid := npc["Default"]; + // display_msg("Change fid: " + fid + ", npc: " + npc[armorType] + ", default:" + defaultFids[armorType]); + return fid; + end + end + return -1; // engine default +end + +/* + Checks if a party member can use the offered weapon +*/ +procedure check_weapon_change(variable critter, variable weapon, variable isWield) begin + variable npc, newWeaponAnim, weaponAnimList, i; + npc := npcMap[obj_pid(critter)]; + if (npc) then begin + if (isWield) then begin + newWeaponAnim := get_proto_data(obj_pid(weapon), PROTO_WP_ANIM); + if newWeaponAnim then begin // anim code 0 - none/unarmed + weaponAnimList := npc["WeaponAnims"]; + if (weaponAnimList != 0) then begin + foreach (i in string_split(weaponAnimList, ",")) begin + if (newWeaponAnim == atoi(i)) then return -1; // can use (engine default) + end + end + return 0; // can't use + end + end else begin + unWieldWeapon := obj_pid(weapon); + end + end + return -1; // engine default +end + +/* + Finds the first weapon which can be used by the party member in the inventory +*/ +procedure search_alt_weapon(variable critter) begin + variable obj, res, i := 0; + obj := inven_ptr(critter, 0); + while (obj) do begin + if (obj_item_subtype(obj) == item_type_weapon) then begin + if (unWieldWeapon == 0 or unWieldWeapon != obj_pid(obj)) then begin + res := check_weapon_change(critter, obj, 1); + if (res == -1) then begin + altWeapon := obj; + wield_obj_critter(critter, obj); + altWeapon := 0; + break; + end + end + end + i++; + obj := inven_ptr(critter, i); + end + unWieldWeapon := 0; +end + +// for NPCs when they change armor/weapon themselves +procedure invenwield_handler begin + variable critter, item, fid, slot, isWield, canWield; + critter := get_sfall_arg; + item := get_sfall_arg; + slot := get_sfall_arg; + isWield := get_sfall_arg; + + if (/*critter and*/ item and slot == INVEN_TYPE_WORN) then begin + fid := check_armor_change(critter, item, isWield); + if (fid != -1) then begin + if art_exists(fid) then begin + art_change_fid_num(critter, fid); + end else begin + debug_msg("[Error] NPC armor mod: Invenwield missing FID: " + fid); + end + end + end else if (/*critter and*/ item and slot == INVEN_TYPE_RIGHT_HAND) then begin + if (altWeapon == item) then return; + canWield := check_weapon_change(critter, item, isWield); + set_sfall_return(canWield); + if (canWield != -1) then begin + call search_alt_weapon(critter); // wield weapon by script + end + end +end + +// when changing armor from inventory while controlling other NPCs +procedure adjustfid_handler begin + variable fid, armor, weapAnim, currFid, newFid; + if (dude_obj != real_dude_obj) then begin + currFid := get_sfall_arg; + if ((currFid bwand 0x0F000000) != FID_OBJ_CRITTER) then return; + armor := critter_inven_obj(dude_obj, INVEN_TYPE_WORN); + fid := check_armor_change(dude_obj, armor, armor != 0); + if (fid != -1) then begin + weapAnim := currFid bwand 0xF000; + newFid := fid bwand 0xFFFF0FFF bwor weapAnim; + if art_exists(newFid) then begin + set_sfall_arg(0, newFid); + set_sfall_return(newFid); + end else begin + debug_msg("[Error] NPC armor mod: Adjust FID missing: " + newFid); + end + end + end +end + +// when changing weapon from inventory while controlling other NPCs +procedure inventorymove_handler begin + variable slot, item, canWield; + slot := get_sfall_arg; + item := get_sfall_arg; + if (dude_obj != real_dude_obj) then begin + if ((slot == INVEN_TYPE_RIGHT_HAND or slot == INVEN_TYPE_LEFT_HAND) and IS_WEAPON(item)) then begin + canWield := check_weapon_change(dude_obj, item, item != 0); + set_sfall_return(canWield); + end + end +end + +procedure start begin + variable sect, sects, armorTypes, armorType, npc, pid, pids, i; + if game_loaded and (sfall_ver_major >= 4 or sfall_ver_build >= 29) then begin + armorTypes := get_ini_section(modIni, "ArmorTypes"); + armorPidMap := create_array_map; + foreach (armorType: pids in armorTypes) begin + pids := string_split(pids, ","); + foreach (pid in pids) begin + armorPidMap[atoi(pid)] := armorType; + end + end + + defaultFids := get_ini_section(modIni, "Default"); + fix_array(defaultFids); + foreach (armorType: i in defaultFids) begin + defaultFids[armorType] := atoi(i); + end + + npcMap := create_array_map; + + i := 1; + sect := get_ini_section(modIni, ""+i); + while (sect.PID) do begin + npc := create_array_map; + npc["WeaponAnims"] := sect["WeaponAnims"]; + npc["Default"] := atoi(sect["Default"]); + foreach (armorType: pids in armorTypes) begin + if (sect[armorType]) then begin + npc[armorType] := atoi(sect[armorType]); + end + end + npcMap[atoi(sect.PID)] := npc; + + i += 1; + sect := get_ini_section(modIni, ""+i); + end + + call update_armor_apperance; + + register_hook_proc(HOOK_INVENWIELD, invenwield_handler); + register_hook_proc(HOOK_ADJUSTFID, adjustfid_handler); + register_hook_proc(HOOK_INVENTORYMOVE, inventorymove_handler); + + debug_msg("NPC armor appearance mod: Done."); + end +end + +procedure update_armor_apperance begin + variable npc, arItem, fid; + foreach (npc in party_member_list_critters) begin + if (npc == dude_obj) then continue; + arItem := critter_inven_obj(npc, INVEN_TYPE_WORN); + if (arItem) then begin + fid := check_armor_change(npc, arItem, true); + if (fid == -1 or art_exists(fid) == false) then continue; + art_change_fid_num(npc, fid); + end + end +end diff --git a/artifacts/example_mods/NPCArmor/npcarmor - vanilla.ini b/artifacts/example_mods/NPCArmor/npcarmor - vanilla.ini new file mode 100644 index 00000000..188d171a --- /dev/null +++ b/artifacts/example_mods/NPCArmor/npcarmor - vanilla.ini @@ -0,0 +1,82 @@ +;NPC armor appearance configuration for vanilla Fallout 2. Does not require any new graphics +;Party members will use player's armor appearance just like old B-Team mod + +;WeaponAnims codes +; 1 - Knife (D) +; 2 - Club (E) +; 3 - Sledgehammer (F) +; 4 - Spear (G) +; 5 - Pistol (H) +; 6 - SMG (I) +; 7 - Rifle (J) +; 8 - Big Gun (K) +; 9 - Minigun (L) +; 10 - Rocket Launcher (M) +; 11-15 - sfall additional weapon animation codes + +; This section maps 7 armor types to corresponding armor item PIDs +[ArmorTypes] +Jacket = 74,265 +Leather = 1,379 +Metal = 2,240,380 +Power = 3,232 +AdvPower = 348,349 +Combat = 17,239,381 +Robe = 113,524 + +; Default armor FIDs (the same for all NPCs) +[Default] +Jacket = 16777229 +Leather = 16777228 +Metal = 16777230 +Combat = 16777226 +Power = 16777217 +AdvPower = 16777287 +Robe = 16777218 + +; Sulik +[1] +PID=16777313 +WeaponAnims=1,3,4,6 +Default=16777280 + +; Vic +[2] +PID=16777278 +WeaponAnims=1,5,7 +Default=16777307 + +; Cassidy +[3] +PID=16777305 +WeaponAnims=4,5,7 +Default=16777260 +Leather=16777260 + +; Myron +[4] +PID=16777376 +WeaponAnims=1,5 +Default=16777304 + +; Lenny +[5] +PID=16777323 +WeaponAnims=1,5,6 +Default=16777295 + +; Davin +[6] +PID=16777379 +WeaponAnims=1,2,5 +Default=16777264 + +; Miria +[7] +PID=16777380 +WeaponAnims=1,6 +Default=16777252 +Jacket=16777222 +Leather=16777221 +Metal=16777223 +Combat=16777219 diff --git a/artifacts/example_mods/NPCArmor/npcarmor.ini b/artifacts/example_mods/NPCArmor/npcarmor.ini new file mode 100644 index 00000000..4b38cd15 --- /dev/null +++ b/artifacts/example_mods/NPCArmor/npcarmor.ini @@ -0,0 +1,89 @@ +;WeaponAnims codes +; 1 - Knife (D) +; 2 - Club (E) +; 3 - Sledgehammer (F) +; 4 - Spear (G) +; 5 - Pistol (H) +; 6 - SMG (I) +; 7 - Rifle (J) +; 8 - Big Gun (K) +; 9 - Minigun (L) +; 10 - Rocket Launcher (M) +; 11-15 - sfall additional weapon animation codes + +; This section maps 7 armor types to corresponding armor item PIDs +[ArmorTypes] +Jacket = 74,265 +Leather = 1,379 +Metal = 2,240,380 +Power = 3,232 +AdvPower = 348,349 +Combat = 17,239,381 +Robe = 113,524 + +; Default armor FIDs (the same for all NPCs) +[Default] +Power = 16777217 +AdvPower = 16777287 +Robe = 16777218 + +; Sulik +[1] +PID=16777313 +WeaponAnims=1,3,4,6,14 +Default=16777280 +Jacket=16777321 +Leather=16777325 +Metal=16777323 +Combat=16777322 +Power=16777324 + +; Vic +[2] +PID=16777278 +WeaponAnims=1,5,7,13,14 +Default=16777307 +Jacket=16777329 +Leather=16777333 +Metal=16777331 +Combat=16777330 +Power=16777332 + +; Cassidy +[3] +PID=16777305 +WeaponAnims=4,5,7,13 +Default=16777354 +Jacket=16777351 +Leather=16777260 +Metal=16777327 +Combat=16777326 +Power=16777328 + +; Myron +[4] +PID=16777376 +WeaponAnims=1,5,14 +Default=16777304 +Combat=16777350 +Power=16777349 + +; Cat Jules (RP) +[5] +PID=16777720 +WeaponAnims=1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 +Default=16777353 +Jacket=16777346 +Leather=16777347 +Metal=16777348 +Combat=16777226 + +; Kitsune (RP) +[6] +PID=16777718 +WeaponAnims=1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 +Default=16777222 +Jacket=16777222 +Leather=16777221 +Metal=16777223 +Combat=16777219 diff --git a/artifacts/example_mods/NPCArmor/readme.txt b/artifacts/example_mods/NPCArmor/readme.txt new file mode 100644 index 00000000..fdd0048d --- /dev/null +++ b/artifacts/example_mods/NPCArmor/readme.txt @@ -0,0 +1,14 @@ +NPC Armor Appearance mod +------------------------ + +This is the same mod as the one included in sfall 4.x modders pack. Used to replace the scripted part of B-Team mod. +Appropriate graphics are required for this mod to work, or you can set party members to use player's armor appearance instead. +Can be adopted to any mod by adjusting armor PIDs, allowed weapon anim codes, NPC PIDs and NPC FIDs in INI file. + + +Requires sfall 3.8.29 or higher + +To use, copy gl_npcarmor.int to your scripts folder, and copy npcarmor.ini to the same directory as sfall. + +The default npcarmor.ini is set up for Restoration Project 2.3.3. +Check the included "npcarmor - vanilla.ini" for an example that does not require any new graphics.