Added an additional '"Can't Use" flag to misc flags in item objects

* it makes the weapon object unusable in combat.

Updated gl_npcarmor script.
Edits to header files and hookscripts.md.
This commit is contained in:
NovaRain
2021-09-03 21:30:12 +08:00
parent edc2755ef6
commit 806cc765bb
9 changed files with 189 additions and 94 deletions
@@ -11,7 +11,7 @@
Requires sfall 3.8.29 or higher Requires sfall 3.8.29 or higher
version 1.1 version 1.4
*/ */
@@ -79,13 +79,13 @@ procedure check_weapon_change(variable critter, variable weapon, variable isWiel
end end
/* /*
Finds the first weapon which can be used by the party member in the inventory Finds the first weapon that can be used by the party member in the inventory
*/ */
procedure search_alt_weapon(variable critter) begin procedure search_alt_weapon(variable critter) begin
variable obj, res, i := 0; variable obj, res, i := 0;
obj := inven_ptr(critter, 0); obj := inven_ptr(critter, 0);
while (obj) do begin while (obj) do begin
if (obj_item_subtype(obj) == item_type_weapon) then begin if (obj_item_subtype(obj) == item_type_weapon and weapon_is_unusable(obj) == false) then begin
if (unWieldWeapon == 0 or unWieldWeapon != obj_pid(obj)) then begin if (unWieldWeapon == 0 or unWieldWeapon != obj_pid(obj)) then begin
res := check_weapon_change(critter, obj, 1); res := check_weapon_change(critter, obj, 1);
if (res == -1) then begin if (res == -1) then begin
+26 -21
View File
@@ -120,26 +120,29 @@
#define MSGBOX_YESNO (0x10) // use YES/NO buttons instead of DONE #define MSGBOX_YESNO (0x10) // use YES/NO buttons instead of DONE
#define MSGBOX_CLEAN (0x20) // no buttons #define MSGBOX_CLEAN (0x20) // no buttons
//remove inven obj defines //remove inven obj defines for the 4th argument to hs_removeinvobj
#define RMOBJ_CONSUME_DRUG 4666772 #define RMOBJ_CONSUME_DRUG 4666772 // (inven_action_cursor_)
#define RMOBJ_CONTAINER 4683293 // same as RMOBJ_TRADE #define RMOBJ_CONTAINER 4683293 // same as RMOBJ_TRADE (item_move_func_)
#define RMOBJ_USE_OBJ 4666865 #define RMOBJ_USE_OBJ 4666865 // (inven_action_cursor_)
#define RMOBJ_EQUIP_ARMOR 4658121 #define RMOBJ_EQUIP_ARMOR 4658121 // (inven_pickup_)
#define RMOBJ_EQUIP_WEAPON 4658675 #define RMOBJ_EQUIP_WEAPON 4658675 // (switch_hand_)
#define RMOBJ_UNLOAD_WEAPON 4667030 #define RMOBJ_UNLOAD_WEAPON 4667030 // (inven_action_cursor_)
//#define RMOBJ_LOAD_WEAPON 4831349 // same as RMOBJ_DROP //#define RMOBJ_LOAD_WEAPON 4831349 // same as RMOBJ_DROP (obj_remove_from_inven_)
#define RMOBJ_USE_DRUG_ON 4834866 #define RMOBJ_USE_DRUG_ON 4834866 // (obj_use_item_on_)
#define RMOBJ_STEAL_VIEW 4668206 #define RMOBJ_STEAL_VIEW 4668206 // (loot_container_)
//#define RMOBJ_DROP_DYNAMITE 4666865 // same as USE_OBJ //#define RMOBJ_DROP_DYNAMITE 4666865 // same as RMOBJ_USE_OBJ
#define RMOBJ_ITEM_DESTROYED 4543215 #define RMOBJ_ITEM_DESTROYED 4543215 // (op_destroy_object_)
#define RMOBJ_ITEM_REMOVED 4548572 #define RMOBJ_ITEM_REMOVED 4548572 // (op_rm_obj_from_inven_)
#define RMOBJ_ARMOR_EQUIPED 4651961 #define RMOBJ_ARMOR_EQUIPED 4651961 // (setup_inventory_)
#define RMOBJ_LEFT_HAND_EQUIPED 4651899 #define RMOBJ_LEFT_HAND_EQUIPED 4651899 // (setup_inventory_)
#define RMOBJ_RIGHT_HAND_EQUIPED 4651934 #define RMOBJ_RIGHT_HAND_EQUIPED 4651934 // (setup_inventory_)
#define RMOBJ_RM_MULT_OBJS 4563866 #define RMOBJ_RM_MULT_OBJS 4563866 // (op_rm_mult_objs_from_inven_)
#define RMOBJ_REPLACE_WEAPON 4658526 #define RMOBJ_REPLACE_WEAPON 4658526 // (switch_hand_)
#define RMOBJ_THROW 4266040 #define RMOBJ_THROW 4266040 // (action_ranged_)
#define RMOBJ_SUB_CONTAINER 4683191 // search and remove the item from nested containers in the inventory #define RMOBJ_SUB_CONTAINER 4683191 // search and remove the item from nested containers in the inventory (item_remove_mult_)
#define RMOBJ_AI_USE_DRUG_ON 4359920 // remove before AI uses the drug in combat (ai_check_drugs_)
//#define RMOBJ_AI_USE_DRUG_ON_1 4359639 // same as RMOBJ_AI_USE_DRUG_ON (obsolete, use only for sfall before 4.3.1/3.8.31)
//#define RMOBJ_AI_USE_DRUG_ON_2 4360176 // same as RMOBJ_AI_USE_DRUG_ON (obsolete, use only for sfall before 4.3.1/3.8.31)
// common prototype offsets for get/set_proto_data // common prototype offsets for get/set_proto_data
#define PROTO_PID (1) #define PROTO_PID (1)
@@ -330,9 +333,11 @@
#define OBJ_DATA_CUR_FRM (0x18) // current frame number #define OBJ_DATA_CUR_FRM (0x18) // current frame number
#define OBJ_DATA_ROTATION (0x1C) #define OBJ_DATA_ROTATION (0x1C)
#define OBJ_DATA_FID (0x20) #define OBJ_DATA_FID (0x20)
//#define OBJ_DATA_FLAGS (0x24) // the same flags set in prototypes (PROTO_FLAG)
#define OBJ_DATA_ELEVATION (0x28) #define OBJ_DATA_ELEVATION (0x28)
#define OBJ_DATA_MISC_FLAGS (0x38)
#define OBJ_DATA_PID (0x64) #define OBJ_DATA_PID (0x64)
#define OBJ_DATA_CID (0x68) // combat ID, used for savegame #define OBJ_DATA_CID (0x68) // combat ID, used by critters in savegame (don't change while in combat)
#define OBJ_DATA_SID (0x78) // script ID #define OBJ_DATA_SID (0x78) // script ID
#define OBJ_DATA_SCRIPT_INDEX (0x80) // script index number in scripts.lst #define OBJ_DATA_SCRIPT_INDEX (0x80) // script index number in scripts.lst
// items // items
+24 -14
View File
@@ -1,7 +1,7 @@
#ifndef SFALL_H #ifndef SFALL_H
#define SFALL_H #define SFALL_H
//Recognised modes for set_shader_mode and get_game_mode // Recognised modes for set_shader_mode and get_game_mode
#define WORLDMAP (0x1) #define WORLDMAP (0x1)
#define DIALOG (0x4) #define DIALOG (0x4)
#define ESCMENU (0x8) #define ESCMENU (0x8)
@@ -24,7 +24,7 @@
#define COUNTERWIN (0x100000) // counter window for moving multiple items or setting a timer #define COUNTERWIN (0x100000) // counter window for moving multiple items or setting a timer
#define SPECIAL (0x80000000) #define SPECIAL (0x80000000)
//Valid arguments to register_hook // Valid arguments to register_hook
#define HOOK_TOHIT (0) #define HOOK_TOHIT (0)
#define HOOK_AFTERHITROLL (1) #define HOOK_AFTERHITROLL (1)
#define HOOK_CALCAPCOST (2) #define HOOK_CALCAPCOST (2)
@@ -54,7 +54,7 @@
#define HOOK_ADJUSTFID (26) #define HOOK_ADJUSTFID (26)
#define HOOK_GAMEMODECHANGE (31) #define HOOK_GAMEMODECHANGE (31)
//Valid arguments to list_begin // Valid arguments to list_begin
#define LIST_CRITTERS (0) #define LIST_CRITTERS (0)
#define LIST_GROUNDITEMS (1) #define LIST_GROUNDITEMS (1)
#define LIST_SCENERY (2) #define LIST_SCENERY (2)
@@ -64,7 +64,7 @@
#define LIST_SPATIAL (6) #define LIST_SPATIAL (6)
#define LIST_ALL (9) #define LIST_ALL (9)
//Valid window types for get_window_attribute // Valid window types for get_window_attribute
#define WINTYPE_INVENTORY (0) // any inventory window (player/loot/use/barter) #define WINTYPE_INVENTORY (0) // any inventory window (player/loot/use/barter)
#define WINTYPE_DIALOG (1) #define WINTYPE_DIALOG (1)
#define WINTYPE_PIPBOY (2) #define WINTYPE_PIPBOY (2)
@@ -75,14 +75,14 @@
#define WINTYPE_ESCMENU (7) // escape menu #define WINTYPE_ESCMENU (7) // escape menu
#define WINTYPE_AUTOMAP (8) #define WINTYPE_AUTOMAP (8)
//Valid flags for force_encounter_with_flags // Valid flags for force_encounter_with_flags
#define ENCOUNTER_FLAG_NO_CAR (0x1) #define ENCOUNTER_FLAG_NO_CAR (0x1)
#define ENCOUNTER_FLAG_LOCK (0x2) // block new forced encounter by the next function call until the current specified encounter occurs #define ENCOUNTER_FLAG_LOCK (0x2) // block new forced encounter by the next function call until the current specified encounter occurs
#define ENCOUNTER_FLAG_NO_ICON (0x4) // disable displaying the flashing icon #define ENCOUNTER_FLAG_NO_ICON (0x4) // disable displaying the flashing icon
#define ENCOUNTER_FLAG_ICON_SP (0x8) // use special encounter icon #define ENCOUNTER_FLAG_ICON_SP (0x8) // use special encounter icon
#define ENCOUNTER_FLAG_FADEOUT (0x10) // fade out the screen on encounter (Note: you yourself should restore the fade screen when entering the encounter) #define ENCOUNTER_FLAG_FADEOUT (0x10) // fade out the screen on encounter (Note: you yourself should restore the fade screen when entering the encounter)
//The attack types returned by get_attack_type // The attack types returned by get_attack_type
#define ATKTYPE_LWEP1 (0) #define ATKTYPE_LWEP1 (0)
#define ATKTYPE_LWEP2 (1) #define ATKTYPE_LWEP2 (1)
#define ATKTYPE_RWEP1 (2) #define ATKTYPE_RWEP1 (2)
@@ -104,18 +104,18 @@
#define ATKTYPE_HOOKKICK (18) #define ATKTYPE_HOOKKICK (18)
#define ATKTYPE_PIERCINGKICK (19) #define ATKTYPE_PIERCINGKICK (19)
//Some possible values for the 4th argument to hs_removeinvobj // Some possible values for the 4th argument to hs_removeinvobj
#define RMOBJ_DROP (0x49B875) //If the object is dropped manually by the player from the inventory screen #define RMOBJ_DROP (0x49B875) // If the object is dropped manually by the player from the inventory screen
#define RMOBJ_TRADE (0x47761D) //If the object is offered up as a trade #define RMOBJ_TRADE (0x47761D) // If the object is offered up as a trade
#define RMOBJ_DROPMULTI (0x45C1CF) //When dropping a part of a stack (RMOBJ_DROP occures first) #define RMOBJ_DROPMULTI (0x45C1CF) // When dropping a part of a stack (RMOBJ_DROP occurs first)
//Return values for "typeof" // Return values for "typeof"
#define VALTYPE_NONE (0) // not used yet #define VALTYPE_NONE (0) // not used yet
#define VALTYPE_INT (1) #define VALTYPE_INT (1)
#define VALTYPE_FLOAT (2) #define VALTYPE_FLOAT (2)
#define VALTYPE_STR (3) #define VALTYPE_STR (3)
//Arrays defines /* ARRAYS FUNCTION DEFINES */
// create persistent list // create persistent list
#define create_array_list(size) (create_array(size, 0)) #define create_array_list(size) (create_array(size, 0))
@@ -246,6 +246,9 @@
#define ADD_PERK_MODE_PERK (2) // add to the player's perks list #define ADD_PERK_MODE_PERK (2) // add to the player's perks list
#define ADD_PERK_MODE_REMOVE (4) // remove from the list of selectable perks (after added to the player) #define ADD_PERK_MODE_REMOVE (4) // remove from the list of selectable perks (after added to the player)
/* MISC FUNCTION MACROS */
// instantly apply the item to dude_obj (w/o animation) // instantly apply the item to dude_obj (w/o animation)
#define use_item_on_dude(item) set_self(dude_obj); \ #define use_item_on_dude(item) set_self(dude_obj); \
set_self(dude_obj); \ set_self(dude_obj); \
@@ -260,8 +263,14 @@
// checks if the specified PID number exists in the list of registered protos // checks if the specified PID number exists in the list of registered protos
#define check_pid(pid) (get_proto_data(pid, 0) != -1) #define check_pid(pid) (get_proto_data(pid, 0) != -1)
// sets the status of an unusable weapon that cannot be used in combat
#define set_weapon_unusable(item) set_object_data(item, OBJ_DATA_MISC_FLAGS, get_object_data(item, OBJ_DATA_MISC_FLAGS) bwor 0x00000010)
#define set_weapon_usable(item) set_object_data(item, OBJ_DATA_MISC_FLAGS, get_object_data(item, OBJ_DATA_MISC_FLAGS) bwand 0xFFFFFFEF)
#define weapon_is_unusable(item) (get_object_data(item, OBJ_DATA_MISC_FLAGS) bwand 0x00000010)
/* SFALL_FUNCX MACROS */
/* sfall_funcX macros */
#define add_extra_msg_file(name) sfall_func1("add_extra_msg_file", name) #define add_extra_msg_file(name) sfall_func1("add_extra_msg_file", name)
#define add_global_timer_event(time, fixedParam) sfall_func2("add_g_timer_event", time, fixedParam) #define add_global_timer_event(time, fixedParam) sfall_func2("add_g_timer_event", time, fixedParam)
#define add_iface_tag sfall_func0("add_iface_tag") #define add_iface_tag sfall_func0("add_iface_tag")
@@ -360,7 +369,8 @@
#define win_fill_color(x, y, width, height, color) sfall_func5("win_fill_color", x, y, width, height, color) #define win_fill_color(x, y, width, height, color) sfall_func5("win_fill_color", x, y, width, height, color)
/* sfall metarule3 function macros */ /* SFALL METARULE3 FUNCTION MACROS */
// sets the number of days (range 1...127) for the Frank Horrigan encounter, or disable the encounter if days is set to 0 // sets the number of days (range 1...127) for the Frank Horrigan encounter, or disable the encounter if days is set to 0
#define set_horrigan_days(day) metarule3(200, day, 0, 0) #define set_horrigan_days(day) metarule3(200, day, 0, 0)
// clears the keyboard input buffer, use it in the HOOK_KEYPRESS hook to clear keyboard events before calling functions that are waiting for keyboard input // clears the keyboard input buffer, use it in the HOOK_KEYPRESS hook to clear keyboard events before calling functions that are waiting for keyboard input
+14 -12
View File
@@ -87,7 +87,7 @@ The defines to use for the hookID are in **sfall.h**.
#### `HOOK_TOHIT (hs_tohit.int)` #### `HOOK_TOHIT (hs_tohit.int)`
Runs when Fallout is calculating the chances of an attack striking a target. Runs when Fallout is calculating the chances of an attack striking a target.<br>
Runs after the hit chance is fully calculated normally, including applying the 95% cap. Runs after the hit chance is fully calculated normally, including applying the 95% cap.
``` ```
@@ -125,8 +125,8 @@ Critter ret2 - Override the target of the attack
#### `HOOK_CALCAPCOST (hs_calcapcost.int)` #### `HOOK_CALCAPCOST (hs_calcapcost.int)`
Runs whenever Fallout is calculating the AP cost of using the weapon (or unarmed attack). Doesn't run for using other item types or moving. Runs whenever Fallout is calculating the AP cost of using the weapon (or unarmed attack). Doesn't run for using other item types or moving.<br>
Note that the first time a game is loaded, this script doesn't run before the initial interface is drawn, so if the script effects the AP cost of whatever is in the player's hands at the time the wrong AP cost will be shown. It will be fixed the next time the interface is redrawn. Note that the first time a game is loaded, this script doesn't run before the initial interface is drawn, so if the script effects the AP cost of whatever is in the player's hands at the time the wrong AP cost will be shown. It will be fixed the next time the interface is redrawn.<br>
You can get the weapon object by checking item slot based on attack type (`ATKTYPE_LWEP1`, `ATKTYPE_LWEP2`, etc) and then calling `critter_inven_obj`. You can get the weapon object by checking item slot based on attack type (`ATKTYPE_LWEP1`, `ATKTYPE_LWEP2`, etc) and then calling `critter_inven_obj`.
``` ```
@@ -144,6 +144,7 @@ int ret0 - The new AP cost
#### `HOOK_DEATHANIM1 (hs_deathanim1.int)` #### `HOOK_DEATHANIM1 (hs_deathanim1.int)`
Runs before Fallout tries to calculate the death animation. Lets you switch out which weapon Fallout sees. Runs before Fallout tries to calculate the death animation. Lets you switch out which weapon Fallout sees.
Does not run for critters in the knockdown/out state. Does not run for critters in the knockdown/out state.
``` ```
@@ -160,8 +161,9 @@ int ret0 - The pid of an object to override the attacking weapon with
#### `HOOK_DEATHANIM2 (hs_deathanim2.int)` #### `HOOK_DEATHANIM2 (hs_deathanim2.int)`
Runs after Fallout has calculated the death animation. Lets you set your own custom frame id, so more powerful than `HOOK_DEATHANIM1`, but performs no validation. Runs after Fallout has calculated the death animation. Lets you set your own custom frame id, so more powerful than `HOOK_DEATHANIM1`, but performs no validation.<br>
When using `critter_dmg` function, this script will also run. In that case weapon pid will be -1 and attacker will point to an object with `obj_art_fid == 0x20001F5`. When using `critter_dmg` function, this script will also run. In that case weapon pid will be -1 and attacker will point to an object with `obj_art_fid == 0x20001F5`.
Does not run for critters in the knockdown/out state. Does not run for critters in the knockdown/out state.
``` ```
@@ -220,7 +222,7 @@ Critter arg0 - The critter that just died
#### `HOOK_FINDTARGET (hs_findtarget.int)` #### `HOOK_FINDTARGET (hs_findtarget.int)`
Runs when the AI is trying to pick a target in combat. Fallout first chooses a list of 4 likely suspects, then normally sorts them in order of weakness/distance/etc depending on the AI caps of the attacker. Runs when the AI is trying to pick a target in combat. Fallout first chooses a list of 4 likely suspects, then normally sorts them in order of weakness/distance/etc depending on the AI caps of the attacker.<br>
This hook replaces that sorting function, allowing you to sort the targets in some arbitrary way. This hook replaces that sorting function, allowing you to sort the targets in some arbitrary way.
The return values can include critters that weren't in the list of possible targets, but the additional targets may still be discarded later on in the combat turn if they are out of the attackers perception or the chance of a successful hit is too low. The list of possible targets often includes duplicated entries, but this is fixed in sfall 4.2.3/3.8.23. The return values can include critters that weren't in the list of possible targets, but the additional targets may still be discarded later on in the combat turn if they are out of the attackers perception or the chance of a successful hit is too low. The list of possible targets often includes duplicated entries, but this is fixed in sfall 4.2.3/3.8.23.
@@ -340,10 +342,10 @@ int ret0 - the new AP cost
------------------------------------------- -------------------------------------------
#### DEPRECATED HOOKS: #### DEPRECATED HOOKS:
* `HOOK_HEXMOVEBLOCKING (hs_hexmoveblocking.int)` ##### `HOOK_HEXMOVEBLOCKING (hs_hexmoveblocking.int)`
* `HOOK_HEXAIBLOCKING (hs_hexaiblocking.int)` ##### `HOOK_HEXAIBLOCKING (hs_hexaiblocking.int)`
* `HOOK_HEXSHOOTBLOCKING (hs_hexshootblocking.int)` ##### `HOOK_HEXSHOOTBLOCKING (hs_hexshootblocking.int)`
* `HOOK_HEXSIGHTBLOCKING (hs_hexsightblocking.int)` ##### `HOOK_HEXSIGHTBLOCKING (hs_hexsightblocking.int)`
Run when checking to see if a hex blocks movement or shooting. (or ai-ing, presumably...) Run when checking to see if a hex blocks movement or shooting. (or ai-ing, presumably...)
@@ -501,7 +503,7 @@ int ret0 - overrides the returned result of the function:
#### `HOOK_INVENTORYMOVE (hs_inventorymove.int)` #### `HOOK_INVENTORYMOVE (hs_inventorymove.int)`
Runs before moving items between inventory slots in dude interface. You can override the action. Runs before moving items between inventory slots in dude interface. You can override the action.<br>
What you can NOT do with this hook: What you can NOT do with this hook:
- force moving items to inappropriate slots (like gun in armor slot) - force moving items to inappropriate slots (like gun in armor slot)
@@ -531,7 +533,7 @@ int ret0 - Override setting (-1 - use engine handler, any other value - prev
#### `HOOK_INVENWIELD (hs_invenwield.int)` #### `HOOK_INVENWIELD (hs_invenwield.int)`
Runs before causing a critter or the player to wield/unwield an armor or a weapon (except when using the inventory by PC). Runs before causing a critter or the player to wield/unwield an armor or a weapon (except when using the inventory by PC).<br>
An example usage would be to change critter art depending on armor being used or to dynamically customize weapon animations. An example usage would be to change critter art depending on armor being used or to dynamically customize weapon animations.
__NOTE:__ When replacing a previously wielded armor or weapon, the unwielding hook will not be executed. __NOTE:__ When replacing a previously wielded armor or weapon, the unwielding hook will not be executed.
@@ -551,7 +553,7 @@ int ret0 - overrides hard-coded handler (-1 - use engine handler, any other
#### `HOOK_ADJUSTFID (hs_adjustfid.int)` #### `HOOK_ADJUSTFID (hs_adjustfid.int)`
Runs after calculating character figure FID on the inventory screen, whenever the game decides that character appearance might change. Runs after calculating character figure FID on the inventory screen, whenever the game decides that character appearance might change.<br>
Also happens on other screens, like barter. Also happens on other screens, like barter.
__NOTE:__ FID has following format: `0x0ABBCDDD`, where: `A` - object type, `BB` - animation code (always 0 in this case), `C` - weapon code, `DDD` - FRM index in LST file. __NOTE:__ FID has following format: `0x0ABBCDDD`, where: `A` - object type, `BB` - animation code (always 0 in this case), `C` - weapon code, `DDD` - FRM index in LST file.
+55
View File
@@ -118,6 +118,54 @@ end:
} }
} }
static void __declspec(naked) ai_can_use_weapon_hack() {
using namespace Fields;
__asm {
test dword ptr [esi + miscFlags], MISCFLG_CantUse;
jnz cantUse;
mov eax, [edi + damageFlags];
retn;
cantUse:
mov al, 0xFF;
retn;
}
}
static void __declspec(naked) can_use_weapon_hook() {
static const DWORD cant_use_weapon_Ret = 0x477F9F;
using namespace Fields;
__asm {
call item_get_type_;
cmp eax, item_type_weapon;
je checkFlag;
retn; // eax - type
checkFlag:
test dword ptr [edx + miscFlags], MISCFLG_CantUse;
jnz cantUse;
retn; // eax - type
cantUse:
add esp, 4;
jmp cant_use_weapon_Ret;
}
}
// Note: in ai_try_attack_, the attacker will not be able to change unusable weapon, as it happens with crippled arms
static void __declspec(naked) combat_check_bad_shot_hack() {
static const DWORD combat_check_bad_shot_Ret = 0x42673A;
using namespace Fields;
__asm {
test dword ptr [ecx + miscFlags], MISCFLG_CantUse;
jnz cantUse;
mov eax, [esi + damageFlags];
test al, DAM_CRIP_ARM_LEFT;
retn;
cantUse:
mov eax, 4; // result same as TargetDead
add esp, 4;
jmp combat_check_bad_shot_Ret;
}
}
void __stdcall SetBlockCombat(long toggle) { void __stdcall SetBlockCombat(long toggle) {
combatDisabled = toggle != 0; combatDisabled = toggle != 0;
} }
@@ -599,6 +647,13 @@ void Combat_Init() {
HookCall(0x45F626, intface_use_item_hook); // jnz hook HookCall(0x45F626, intface_use_item_hook); // jnz hook
HookCall(0x4432A6, game_handle_input_hook); HookCall(0x4432A6, game_handle_input_hook);
// Add an additional "Can't Use" flag to the misc flags of item objects (offset 0x0038)
// Misc Flags:
// 0x00000010 - Can't Use (makes the weapon object unusable in combat)
HookCall(0x477F4C, can_use_weapon_hook);
MakeCall(0x4298F4, ai_can_use_weapon_hack);
MakeCall(0x426669, combat_check_bad_shot_hack);
CombatProcPatch(); CombatProcPatch();
// Prevents NPC aggression when non-hostile NPCs accidentally hit the player or members of the player's team // Prevents NPC aggression when non-hostile NPCs accidentally hit the player or members of the player's team
+55 -41
View File
@@ -110,10 +110,10 @@ enum BodyPart : long {
enum CritterFlags : long enum CritterFlags : long
{ {
CFLG_Sneak = 0x01, // Can sneak ? CFLG_Sneak = 0x01, // Can sneak ? (unused)
CFLG_Barter = 0x02, // Can trade with CFLG_Barter = 0x02, // Can trade with
CFLG_Level = 0x04, // Level received ? CFLG_Level = 0x04, // Level received ? (unused)
CFLG_Addict = 0x08, // Drug addiction ? CFLG_Addict = 0x08, // Drug addiction ? (unused)
CFLG_NoSteal = 0x20, // Can't be stolen from CFLG_NoSteal = 0x20, // Can't be stolen from
CFLG_NoDrop = 0x40, // Doesn't drop items CFLG_NoDrop = 0x40, // Doesn't drop items
CFLG_NoLimbs = 0x80, // Can't lose limbs CFLG_NoLimbs = 0x80, // Can't lose limbs
@@ -126,7 +126,7 @@ enum CritterFlags : long
CFLG_NoKnockBack = 0x4000, // Can't be knocked back CFLG_NoKnockBack = 0x4000, // Can't be knocked back
}; };
enum ItemFlags : long enum ItemFlags : unsigned long // for FlagsExt
{ {
// Weapon Flags: // Weapon Flags:
IFLG_BigGun = 0x00000100, IFLG_BigGun = 0x00000100,
@@ -140,6 +140,14 @@ enum ItemFlags : long
IFLG_HiddenItem = 0x08000000 // item is hidden IFLG_HiddenItem = 0x08000000 // item is hidden
}; };
enum MiscFlags : unsigned long
{
MISCFLG_Opened = 0x00000001,
MISCFLG_CantUse = 0x00000010, // determines whether the weapon can be used in combat (sfall flag)
MISCFLG_Locked = 0x02000000,
MISCFLG_Jammed = 0x04000000,
};
enum DamageFlag : unsigned long enum DamageFlag : unsigned long
{ {
DAM_KNOCKED_OUT = 0x1, DAM_KNOCKED_OUT = 0x1,
@@ -235,10 +243,10 @@ namespace ObjectFlag {
Flat = 0x00000008, Flat = 0x00000008,
NoBlock = 0x00000010, NoBlock = 0x00000010,
Lighting = 0x00000020, Lighting = 0x00000020,
Temp = 0x00000400, Temp = 0x00000400, // ???
MultiHex = 0x00000800, MultiHex = 0x00000800,
NoHighlight = 0x00001000, NoHighlight = 0x00001000,
Used = 0x00002000, Used = 0x00002000, // set if there was/is any event for the object
TransRed = 0x00004000, TransRed = 0x00004000,
TransNone = 0x00008000, TransNone = 0x00008000,
TransWall = 0x00010000, TransWall = 0x00010000,
@@ -248,7 +256,7 @@ namespace ObjectFlag {
Left_Hand = 0x01000000, Left_Hand = 0x01000000,
Right_Hand = 0x02000000, Right_Hand = 0x02000000,
Worn = 0x04000000, Worn = 0x04000000,
HiddenItem = 0x08000000, Unused = 0x08000000, // reserved
WallTransEnd = 0x10000000, WallTransEnd = 0x10000000,
LightThru = 0x20000000, LightThru = 0x20000000,
Seen = 0x40000000, Seen = 0x40000000,
@@ -742,49 +750,55 @@ enum CombatStateFlag : long
namespace Fields { namespace Fields {
enum CommonObj : long enum CommonObj : long
{ {
id = 0x00, id = 0x00, // saveable
tile = 0x04, tile = 0x04, // saveable
x = 0x08, x = 0x08, // saveable
y = 0x0C, y = 0x0C, // saveable
sx = 0x10, sx = 0x10, // saveable
sy = 0x14, sy = 0x14, // saveable
frm = 0x18, frm = 0x18, // saveable
rotation = 0x1C, rotation = 0x1C, // saveable
artFid = 0x20, artFid = 0x20, // saveable
flags = 0x24, flags = 0x24, // saveable
elevation = 0x28, elevation = 0x28, // saveable
inventory = 0x2C, inventory = 0x2C, // saveable
protoId = 0x64, protoId = 0x64, // saveable
cid = 0x68, // combatID, don't change while in combat cid = 0x68, // saveable (critter CombatID, don't change while in combat)
lightDistance = 0x6C, lightDistance = 0x6C, // saveable
lightIntensity = 0x70, lightIntensity = 0x70, // saveable
outline = 0x74, outline = 0x74, // saveable
scriptId = 0x78, scriptId = 0x78, // saveable
owner = 0x7C, owner = 0x7C,
scriptIndex = 0x80, scriptIndex = 0x80, // saveable
}; };
enum CritterObj : long enum CritterObj : long
{ {
reaction = 0x38, reaction = 0x38, // saveable
combatState = 0x3C, combatState = 0x3C, // saveable
movePoints = 0x40, movePoints = 0x40, // saveable
damageFlags = 0x44, damageFlags = 0x44, // saveable
damageLastTurn = 0x48, damageLastTurn = 0x48, // saveable
aiPacket = 0x4C, aiPacket = 0x4C, // saveable
teamNum = 0x50, teamNum = 0x50, // saveable
whoHitMe = 0x54, whoHitMe = 0x54, // saveable
health = 0x58, health = 0x58, // saveable
rads = 0x5C, rads = 0x5C, // saveable
poison = 0x60, poison = 0x60, // saveable
}; };
enum ItemObj : long enum ItemObj : long
{ {
updatedFlags = 0x38, miscFlags = 0x38, // saveable
charges = 0x3C, charges = 0x3C, // saveable
ammoPid = 0x40, ammoPid = 0x40, // saveable
};
enum SceneryObj : long
{
sceneryFlags = 0x38, // saveable
doorFlags = 0x3C, // saveable
}; };
enum ComputeAttack : long enum ComputeAttack : long
@@ -839,7 +853,7 @@ namespace AIpref {
ATKWHO_whomever_attacking_me = 0, // attack the target that the player is attacking (only for party members) ATKWHO_whomever_attacking_me = 0, // attack the target that the player is attacking (only for party members)
ATKWHO_strongest = 1, // attack stronger targets (will always switch to stronger ones in combat) ATKWHO_strongest = 1, // attack stronger targets (will always switch to stronger ones in combat)
ATKWHO_weakest = 2, // attack weaker targets (will always switch to weaker ones in combat) ATKWHO_weakest = 2, // attack weaker targets (will always switch to weaker ones in combat)
ATKWHO_whomever = 3, // anyone, will attack the chosen target until it dies, or until retaliation occurs (combatai_check_retalization_) ATKWHO_whomever = 3, // anyone, will attack the chosen target until it dies, or until retaliation occurs (combatai_check_retaliation_)
ATKWHO_closest = 4, // only attack near targets ATKWHO_closest = 4, // only attack near targets
}; };
+1
View File
@@ -89,6 +89,7 @@ FUNC(cai_attempt_w_reload_, 0x42AECC)
FUNC(cai_retargetTileFromFriendlyFireSubFunc_, 0x42A410) FUNC(cai_retargetTileFromFriendlyFireSubFunc_, 0x42A410)
FUNC(cai_retargetTileFromFriendlyFire_, 0x42A1D4) FUNC(cai_retargetTileFromFriendlyFire_, 0x42A1D4)
FUNC(can_see_, 0x412BEC) FUNC(can_see_, 0x412BEC)
FUNC(can_use_weapon_, 0x477F3C)
FUNC(check_death_, 0x410814) FUNC(check_death_, 0x410814)
FUNC(check_for_death_, 0x424EE8) FUNC(check_for_death_, 0x424EE8)
FUNC(combat_, 0x422D2C) FUNC(combat_, 0x422D2C)
+11 -3
View File
@@ -137,13 +137,14 @@ struct TGameObj {
union { union {
struct { struct {
long updatedFlags; MiscFlags miscFlags; // aka updated_flags
// for weapons - ammo in magazine, for ammo - amount of ammo in last ammo pack // for weapons - ammo in magazine, for ammo - amount of ammo in last ammo pack
long charges; long charges;
// current type of ammo loaded in magazine // current type of ammo loaded in magazine
long ammoPid; long ammoPid;
long unused[8]; // offset 0x44 long unused[8]; // offset 0x44 (not saved)
} item; } item;
struct { struct {
long reaction; // unused? long reaction; // unused?
// 1 - combat, 2 - enemies out of sight, 4 - running away // 1 - combat, 2 - enemies out of sight, 4 - running away
@@ -190,14 +191,21 @@ struct TGameObj {
} }
} }
} critter; } critter;
struct {
MiscFlags sceneryFlags; // unused for scenery? (aka updated_flags)
MiscFlags doorFlags; // used for doors states open/locked/jammed (aka cur_open_flags)
long unused[9]; // offset 0x40 (not saved)
} scenery;
}; };
DWORD protoId; // object PID DWORD protoId; // object PID
long cid; // combat ID (don't change while in combat) long cid; // combat ID (don't change while in combat)
long lightDistance; long lightDistance;
long lightIntensity; long lightIntensity;
DWORD outline; DWORD outline;
long scriptId; // SID 0x0Y00XXXX: Y - type: 0=s_system, 1=s_spatial, 2=s_time, 3=s_item, 4=s_critter; XXXX - index in scripts.lst; 0xFFFFFFFF no attached script long scriptId; // SID 0x0Y00XXXX: Y - type: 0=s_system, 1=s_spatial, 2=s_time, 3=s_item, 4=s_critter; XXXX - index in scripts.lst; 0xFFFFFFFF no attached script
TGameObj* owner; TGameObj* owner; // not saved
long scriptIndex; long scriptIndex;
inline char Type() { inline char Type() {