Compare commits

..
25 Commits
Author SHA1 Message Date
NovaRain ea921aabbd Merge branch 'develop' 2020-05-21 09:42:23 +08:00
NovaRain b263b69fa3 Renamed all script opcode handlers with op_ prefix
Renamed all metarule functions with mf_ prefix.
2020-05-20 11:30:25 +08:00
NovaRain 6bb56b0f95 Minor code fixes in AI.cpp:
* Fixed NPCs being unable to select a burst attack mode if the line of
fire was blocked.

* Changed the return point of combat_ai_hook_FleeFix to run
ai_check_drugs_ first.

Changed the debug message about missing art file for critters to be
displayed in game only when in sfall debugging mode.
2020-05-19 09:48:46 +08:00
NovaRain 9a4f0c7505 Merge branch 'develop' 2020-05-11 09:35:28 +08:00
NovaRain c89a18522d Fixed ai_move_away_ engine function
Some minor fixes.
2020-05-10 09:56:11 +08:00
NovaRain c7ccb7f2c2 Edited the msg for SkipLoadingGameSettings a bit
Added a few more defines.
2020-05-08 10:44:37 +08:00
NovaRain b25ca683f3 Cosmetic changes to the code:
Use double underscore for stdcall and "asm" keyword.
2020-05-07 12:27:53 +08:00
NovaRain e28b3a5796 Minor code edits to Combat.cpp
Added some function defines.
2020-05-07 12:13:28 +08:00
NovaRain a9c74501df Added checking AP cost to ai_pick_hit_mode_ engine function 2020-05-07 09:47:57 +08:00
NovaRain b03b93d6fc Added a tweak for finding new targets for PMs
* before they would "forget" their current target when trying to find
new ones (only 3), now the current target is included as one of
potential targets.

Tweaked the code of MultiHexPathingFix.
2020-05-05 12:13:11 +08:00
NovaRain 1f696b9f12 Added internal implementation of engine functions with hooks:
* item_w_mp_cost_ with CALCAPCOST
* is_within_perception_ with WITHINPERCEPTION
2020-05-01 10:27:05 +08:00
NovaRain 3d2d1cdf2a Added combat rating check to "Snipe" distance preference fix 2020-05-01 08:00:49 +08:00
NovaRain 42347ac062 Added a fix to reduce friendly fire in burst attacks (experimental) 2020-04-30 16:01:57 +08:00
NovaRain 007b415740 Changed the priority of files in AutoSearchPath
* now they have higher priority than the PatchFileXX options.

Minor code edits/fixes.
2020-04-30 10:13:44 +08:00
NovaRain 35d2491bcb Added a fix for AI behavior for "Snipe" distance preference
Added a check for for the weapon range and the distance to the target
when AI is choosing weapon attack modes.
2020-04-28 10:55:56 +08:00
NovaRain ece76ee726 Changed the fix for AI target selection in commit f731de7
* NPCs will reload the weapon in the same turn (and attack if have
enough AP left) if weapon is empty while selecting targets.

Misc code edits.
2020-04-27 14:25:40 +08:00
NovaRain d6f4a23527 Fixed AllowDShowSound=2 not working
Limited NumSoundBuffers to the max of 32.
Fixed replacing Body_Torso with Body_Uncalled (from commit 7e31713)
Corrected the code in the previous commit.
2020-04-23 12:33:00 +08:00
NovaRain 045ad2f5d7 Added a tweak to the miss message in combat
* if the main target has Flat flag set, remove the message about hitting
another object.

Minor code edits to DebugEditor.cpp & MiscPatches.cpp.
2020-04-22 11:32:03 +08:00
NovaRain 13703f1a3b Improved the fix for placing PID_CORPSE_BLOOD obj on the lower layer
(didn't work correctly after re-entering the map.)

Fixed CorpseDeleteTime not setting the timer correctly.
2020-04-21 10:54:35 +08:00
NovaRain 58bb77d79f Fixed GvarID option behavior in Drugs.ini
Reverted incorrect code change of SpeedPatch.cpp in previous commit.
Some code edits to Explosions.cpp and Perks.cpp.
2020-04-19 09:58:47 +08:00
NovaRain 229371e4ab Added use_item_on_dude macro to sfall.h
Various code edits:
* Implemented more HookCalls/MakeCalls/SafeWriteBatch in code.
* Moved return/jump address consts into their respective functions.
* Changed for-loop with iterators to use pre-increment.
2020-04-18 21:19:22 +08:00
NovaRain 1884e279c7 Fixed ReloadWeaponKey for using any non-weapon item (#84) 2020-04-18 10:44:17 +08:00
NovaRain e81d79e43e Fixed "loot_obj" script function 2020-04-18 08:57:02 +08:00
NovaRain f731de7a25 Fixed AI target selection for no ammo or target out of range cases 2020-04-18 08:33:08 +08:00
NovaRain 0d6bc33279 Re-fixed automatically ending combat
Updated version number.
2020-04-18 07:28:00 +08:00
110 changed files with 1756 additions and 1447 deletions
+9 -2
View File
@@ -13,18 +13,25 @@ Count=0
[1] [1]
; drug item PID ; drug item PID
PID=0 PID=0
; set a limit on the count of first and second delayed effects when using the drug, i.e. if the queue has delayed effects from the drug, ; set a limit on the count of first and second delayed effects when using the drug, i.e. if the queue has delayed effects from the drug,
; and their count is greater or equal to NumEffects, it is not possible to obtain new effects from using the drug ; and their count is greater or equal to NumEffects, it is not possible to obtain new effects from using the drug
; this count is 4 for Buffout/Mentats/Psycho/Jet ; e.g. this count is 4 for Buffout/Mentats/Psycho/Jet
; set -1 to leave this parameter unchanged ; set -1 to leave this parameter unchanged
NumEffects=-1 NumEffects=-1
; the duration of the addiction effect in game minutes (i.e. 1440 = 24 game hours) ; the duration of the addiction effect in game minutes (i.e. 1440 = 24 game hours)
; set to 0 to use the default time (7 days for all drugs except Jet) ; set to 0 to use the default time of 7 days (as all drugs except Jet)
AddictTime=0 AddictTime=0
; the number of the global variable from vault13.gam responsible for displaying addiction in the character screen ; the number of the global variable from vault13.gam responsible for displaying addiction in the character screen
; if you set GvarID with numbers: 21-26, 295, 296, or variable numbers that have already been declared in previous sections,
; the TextID and FrmID options in this section will be ignored
; set to 0 if the addiction is not required ; set to 0 if the addiction is not required
GvarID=0 GvarID=0
; the index number from editor.msg to display the title of the addiction (the description uses the index number of TextID + 100) ; the index number from editor.msg to display the title of the addiction (the description uses the index number of TextID + 100)
TextID=-1 TextID=-1
; the line number (0-indexed) of the corresponding FRM in skilldex.lst ; the line number (0-indexed) of the corresponding FRM in skilldex.lst
FrmID=-1 FrmID=-1
+10 -10
View File
@@ -1,5 +1,5 @@
;sfall configuration settings ;sfall configuration settings
;v4.2.4 ;v4.2.5
[Main] [Main]
;Change to 1 if you want to use command line args to tell sfall to use another ini file. ;Change to 1 if you want to use command line args to tell sfall to use another ini file.
@@ -18,9 +18,9 @@ UseCommandLine=0
;The greater numbers take precedence over lesser numbers ;The greater numbers take precedence over lesser numbers
;PatchFile0=mods\RP_data ;PatchFile0=mods\RP_data
;Path to the folder in which the game will automatically search and load custom .dat files ;Path to the folder in which the game will automatically search and load custom files (by *.dat mask, including folders)
;The data load order of the .dat files in the folder will be in reverse alphabetical order of the filenames ;The data load order of the files in the folder will be in reverse alphabetical order of the filenames
;The .dat files specified in the PatchFileXX options will have higher priority than others ;The files placed in this folder will have higher priority than the PatchFileXX options
;Uncomment the option to specify a different folder path. The default path is <GameRoot>\mods\ ;Uncomment the option to specify a different folder path. The default path is <GameRoot>\mods\
;AutoSearchPath=mods ;AutoSearchPath=mods
@@ -121,7 +121,7 @@ WorldMapTerrainInfo=0
;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX ;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
[Sound] [Sound]
;Sets the number of allowed simultaneous sound effects ;Sets the number of allowed simultaneous sound effects
;Set to 0 to leave the default unchanged (i.e. 4) ;Set to 0 to leave the default unchanged (i.e. 4). The maximum is 32
NumSoundBuffers=0 NumSoundBuffers=0
;Set to 1 to allow attaching sound files to combat float messages ;Set to 1 to allow attaching sound files to combat float messages
@@ -134,7 +134,7 @@ AllowDShowSound=0
;Set to 1 to override the music path used by default (i.e. data\sound\music\) if not present in the cfg ;Set to 1 to override the music path used by default (i.e. data\sound\music\) if not present in the cfg
;Set to 2 to overwrite all occurances of the music path ;Set to 2 to overwrite all occurances of the music path
OverrideMusicDir=2 OverrideMusicDir=1
;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX ;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
[Input] [Input]
@@ -193,7 +193,7 @@ SpeedKey9=0x00
;Set to -1 for either ctrl key, -2 for either alt key or -3 for either shift key ;Set to -1 for either ctrl key, -2 for either alt key or -3 for either shift key
WindowScrollKey=0 WindowScrollKey=0
;A key to press to reload your currently equipped weapon ;A key to press to reload your currently equipped weapon or use the active item
;Set to 0 if you don't want a reload key, or a DX scancode otherwise ;Set to 0 if you don't want a reload key, or a DX scancode otherwise
ReloadWeaponKey=0 ReloadWeaponKey=0
@@ -361,7 +361,7 @@ SingleCore=1
OverrideArtCacheSize=0 OverrideArtCacheSize=0
;Prevents you from saving in combat except at the start of your turn to avoid a few bugs ;Prevents you from saving in combat except at the start of your turn to avoid a few bugs
;Note that even with this option enabled, it is still not advisable to save in combat at all. ;Note that even with this option enabled, it is still not advisable to save in combat at all (obsolete information)
;Set to 2 to block all saving in combat ;Set to 2 to block all saving in combat
SaveInCombatFix=1 SaveInCombatFix=1
@@ -411,7 +411,7 @@ CorpseDeleteTime=6
;Set a number of milliseconds to idle each input loop ;Set a number of milliseconds to idle each input loop
;Set to -1 to disable ;Set to -1 to disable
;Set to 0 to idle only if other processes are waiting for processor time (WinXP/2000: if processes have equal priority) ;Set to 0 to idle only if other processes are waiting for processor time (WinXP/2000: if processes have equal priority)
;Set to 1 (or some higher number if needed, the maximum is 127) to prevent 100% CPU use ;Set to 1 (or some higher number if needed) to prevent 100% CPU use. The maximum is 127
ProcessorIdle=-1 ProcessorIdle=-1
;Set to 1 if using the hero appearance mod ;Set to 1 if using the hero appearance mod
@@ -715,7 +715,7 @@ PartyMemberExtraInfo=0
;that overrides First Aid/Doctor functions has very limited usefulness ;that overrides First Aid/Doctor functions has very limited usefulness
PartyMemberSkillFix=0 PartyMemberSkillFix=0
;Set to 1 to skip loading all game settings except the game/combat difficulty from a saved game ;Set to 1 to skip loading all game settings except the game/combat difficulty from saved games
;Set to 2 to also skip loading the game/combat difficulty settings ;Set to 2 to also skip loading the game/combat difficulty settings
SkipLoadingGameSettings=0 SkipLoadingGameSettings=0
+6
View File
@@ -266,6 +266,12 @@
#define ADD_PERK_MODE_PERK (2) // add to the player's perks #define ADD_PERK_MODE_PERK (2) // add to the player's perks
#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)
// instantly apply the item to dude_obj (w/o animation)
#define use_item_on_dude(item) set_self(dude_obj); \
set_self(dude_obj); \
use_obj_on_obj(item, dude_obj); \
set_self(0)
// 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)
-1
View File
@@ -10,7 +10,6 @@ namespace sfall
std::multimap<long, long> writeAddress; std::multimap<long, long> writeAddress;
static std::vector<long> excludeAddr = { static std::vector<long> excludeAddr = {
0x42A14F, 0x42A178,
0x44E949, 0x44E94A, 0x44E937, 0x4F5F40, 0x4CB850, // from movies.cpp 0x44E949, 0x44E94A, 0x44E937, 0x4F5F40, 0x4CB850, // from movies.cpp
}; };
+3 -2
View File
@@ -166,7 +166,7 @@ void ToggleNpcFlag(fo::GameObject* npc, long flag, bool set) {
} }
} }
// Returns the number of party members in the existing table (begins from 1) // Returns the position of party member in the existing table (begins from 1)
long IsPartyMemberByPid(long pid) { long IsPartyMemberByPid(long pid) {
size_t patryCount = fo::var::partyMemberMaxCount; size_t patryCount = fo::var::partyMemberMaxCount;
if (patryCount) { if (patryCount) {
@@ -178,6 +178,7 @@ long IsPartyMemberByPid(long pid) {
return 0; return 0;
} }
// Returns True if the NPC belongs to the player's potential (set in party.txt) party members (analog of broken isPotentialPartyMember_)
bool IsPartyMember(fo::GameObject* critter) { bool IsPartyMember(fo::GameObject* critter) {
if (critter->id < PLAYER_ID) return false; if (critter->id < PLAYER_ID) return false;
return (IsPartyMemberByPid(critter->protoId) > 0); return (IsPartyMemberByPid(critter->protoId) > 0);
@@ -251,7 +252,7 @@ fo::Window* GetWindow(long winType) {
} }
// Returns an array of objects within the specified radius from the source tile // Returns an array of objects within the specified radius from the source tile
void GetObjectsTileRadius(std::vector<fo::GameObject*> &objs, long sourceTile, long radius, long elev, long type = -1) { void GetObjectsTileRadius(std::vector<fo::GameObject*> &objs, long sourceTile, long radius, long elev, long type) {
for (long tile = 0; tile < 40000; tile++) { for (long tile = 0; tile < 40000; tile++) {
fo::GameObject* obj = fo::func::obj_find_first_at_tile(elev, tile); fo::GameObject* obj = fo::func::obj_find_first_at_tile(elev, tile);
while (obj) { while (obj) {
+3 -2
View File
@@ -72,9 +72,10 @@ long __fastcall IsRadInfluence();
void ToggleNpcFlag(fo::GameObject* npc, long flag, bool set); void ToggleNpcFlag(fo::GameObject* npc, long flag, bool set);
// Returns the number of party members in the existing table (begins from 1) // Returns the position of party member in the existing table (begins from 1)
long IsPartyMemberByPid(long pid); long IsPartyMemberByPid(long pid);
// Returns True if the NPC belongs to the player's potential (set in party.txt) party members (analog of broken isPotentialPartyMember_)
bool IsPartyMember(fo::GameObject* critter); bool IsPartyMember(fo::GameObject* critter);
// Returns the number of local variables of the object script // Returns the number of local variables of the object script
@@ -84,7 +85,7 @@ long __fastcall GetTopWindowID(long xPos, long yPos);
fo::Window* GetWindow(long winType); fo::Window* GetWindow(long winType);
void GetObjectsTileRadius(std::vector<fo::GameObject*> &objs, long sourceTile, long radius, long elev, long type); void GetObjectsTileRadius(std::vector<fo::GameObject*> &objs, long sourceTile, long radius, long elev, long type = -1);
long wmGetCurrentTerrainType(); long wmGetCurrentTerrainType();
+15 -6
View File
@@ -90,6 +90,15 @@ enum Animation : long
ANIM_called_shot_pic = 64, ANIM_called_shot_pic = 64,
}; };
enum AnimCommand : long
{
RB_UNRESERVED = 0x1,
RB_RESERVED = 0x2,
RB_DONTSTAND = 0x4,
RB_UNKNOWN = 0x100,
RB_END_ANIM = 0x200
};
enum CritterFlags : long enum CritterFlags : long
{ {
Sneak = 0x01, // Can sneak ? Sneak = 0x01, // Can sneak ?
@@ -244,7 +253,7 @@ enum ArtType : char
// Some FO2 PIDs possibly used by engine // Some FO2 PIDs possibly used by engine
enum ProtoId : long enum ProtoId : long
{ {
PID_ROCK = 19, // PID_ROCK = 19,
PID_SMALL_ENERGY_CELL = 38, PID_SMALL_ENERGY_CELL = 38,
PID_MICRO_FUSION_CELL = 39, PID_MICRO_FUSION_CELL = 39,
PID_STIMPAK = 40, PID_STIMPAK = 40,
@@ -256,8 +265,8 @@ enum ProtoId : long
PID_GEIGER_COUNTER = 52, PID_GEIGER_COUNTER = 52,
PID_MENTATS = 53, PID_MENTATS = 53,
PID_STEALTH_BOY = 54, PID_STEALTH_BOY = 54,
PID_WATER_CHIP = 55, // PID_WATER_CHIP = 55,
PID_HOLODISK = 58, // PID_HOLODISK = 58,
PID_MOTION_SENSOR = 59, PID_MOTION_SENSOR = 59,
PID_MUTATED_FRUIT = 71, PID_MUTATED_FRUIT = 71,
PID_BIG_BOOK_OF_SCIENCE = 73, PID_BIG_BOOK_OF_SCIENCE = 73,
@@ -268,7 +277,7 @@ enum ProtoId : long
PID_SCOUT_HANDBOOK = 86, PID_SCOUT_HANDBOOK = 86,
PID_BUFFOUT = 87, PID_BUFFOUT = 87,
PID_DOCTORS_BAG = 91, PID_DOCTORS_BAG = 91,
PID_PUMP_PARTS = 98, // PID_PUMP_PARTS = 98,
PID_GUNS_AND_BULLETS = 102, PID_GUNS_AND_BULLETS = 102,
PID_NUKA_COLA = 106, PID_NUKA_COLA = 106,
PID_RAD_X = 109, PID_RAD_X = 109,
@@ -287,7 +296,7 @@ enum ProtoId : long
PID_JET = 259, PID_JET = 259,
PID_JET_ANTIDOTE = 260, PID_JET_ANTIDOTE = 260,
PID_DECK_OF_TRAGIC_CARDS = 306, PID_DECK_OF_TRAGIC_CARDS = 306,
PID_GECK = 366, // PID_GECK = 366,
PID_SOLAR_SCORCHER = 390, PID_SOLAR_SCORCHER = 390,
PID_CAR_TRUNK = 455, PID_CAR_TRUNK = 455,
PID_JESSE_CONTAINER = 467, PID_JESSE_CONTAINER = 467,
@@ -560,7 +569,7 @@ namespace Scripts {
} }
#define STAT_max_derived STAT_poison_resist #define STAT_max_derived STAT_poison_resist
#define STAT_max_stat STAT_current_hp #define STAT_max_stat STAT_current_hp
// Script data types // Script data types
#define VAR_TYPE_INT (0xC001) #define VAR_TYPE_INT (0xC001)
+2 -2
View File
@@ -21,12 +21,12 @@
/* /*
* HOW TO USE ENGINE FUNCTIONS: * HOW TO USE ENGINE FUNCTIONS:
* *
* in ASM code, call offsets directly, don't call wrappers as they might not be _stdcall * in ASM code, call offsets directly, don't call wrappers as they might not be __stdcall
* in C++ code, use wrappers (add new ones if the don't exist yet, see Wrappers_def.h) * in C++ code, use wrappers (add new ones if the don't exist yet, see Wrappers_def.h)
* *
* Note: USE C++! * Note: USE C++!
* 1) Place thin __declspec(naked) hooks, only use minimum ASM to pass values to/from C++ * 1) Place thin __declspec(naked) hooks, only use minimum ASM to pass values to/from C++
* 2) Call _stdcall functions from (1), write those entirely in C++ (with little ASM blocks only to call engine functions, when you are too lazy to add wrapper) * 2) Call __stdcall functions from (1), write those entirely in C++ (with little ASM blocks only to call engine functions, when you are too lazy to add wrapper)
*/ */
namespace fo namespace fo
+4 -4
View File
@@ -202,7 +202,7 @@ const char* __stdcall findCurrentProc(Program* program) {
WRAP_WATCOM_CALL1(findCurrentProc_, program) WRAP_WATCOM_CALL1(findCurrentProc_, program)
} }
const char* _stdcall getmsg(const MessageList* fileAddr, MessageNode* result, long messageId) { const char* __stdcall getmsg(const MessageList* fileAddr, MessageNode* result, long messageId) {
WRAP_WATCOM_CALL3(getmsg_, fileAddr, result, messageId) WRAP_WATCOM_CALL3(getmsg_, fileAddr, result, messageId)
} }
@@ -273,7 +273,7 @@ void __declspec(naked) interpretError(const char* fmt, ...) {
__asm jmp fo::funcoffs::interpretError_ __asm jmp fo::funcoffs::interpretError_
} }
long _stdcall isPartyMember(GameObject* obj) { long __stdcall isPartyMember(GameObject* obj) {
WRAP_WATCOM_CALL1(isPartyMember_, obj) WRAP_WATCOM_CALL1(isPartyMember_, obj)
} }
@@ -358,11 +358,11 @@ GameObject* __stdcall obj_find_next_at_tile() {
WRAP_WATCOM_CALL0(obj_find_next_at_tile_) WRAP_WATCOM_CALL0(obj_find_next_at_tile_)
} }
long _stdcall partyMemberGetCurLevel(GameObject* obj) { long __stdcall partyMemberGetCurLevel(GameObject* obj) {
WRAP_WATCOM_CALL1(partyMemberGetCurLevel_, obj) WRAP_WATCOM_CALL1(partyMemberGetCurLevel_, obj)
} }
long _stdcall perk_level(GameObject* critter, long perkId) { long __stdcall perk_level(GameObject* critter, long perkId) {
WRAP_WATCOM_CALL2(perk_level_, critter, perkId) WRAP_WATCOM_CALL2(perk_level_, critter, perkId)
} }
+4 -4
View File
@@ -99,12 +99,12 @@ void executeProcedure(Program* sptr, long procNum);
long __stdcall get_input(); long __stdcall get_input();
long _stdcall isPartyMember(GameObject* obj); long __stdcall isPartyMember(GameObject* obj);
long __stdcall item_get_type(GameObject* item); long __stdcall item_get_type(GameObject* item);
// searches for message ID in given message file and places result in @result // searches for message ID in given message file and places result in @result
const char* _stdcall getmsg(const MessageList* fileAddr, MessageNode* result, long messageId); const char* __stdcall getmsg(const MessageList* fileAddr, MessageNode* result, long messageId);
// plays SFX sound with given name // plays SFX sound with given name
void __stdcall gsound_play_sfx_file(const char* name); void __stdcall gsound_play_sfx_file(const char* name);
@@ -173,9 +173,9 @@ GameObject* __stdcall obj_find_first_at_tile(long elevation, long tileNum);
GameObject* __stdcall obj_find_next_at_tile(); GameObject* __stdcall obj_find_next_at_tile();
long _stdcall partyMemberGetCurLevel(GameObject* obj); long __stdcall partyMemberGetCurLevel(GameObject* obj);
long _stdcall perk_level(GameObject* critter, long perkId); long __stdcall perk_level(GameObject* critter, long perkId);
// places pointer to a prototype structure into ptrPtr and returns 0 on success or -1 on failure // places pointer to a prototype structure into ptrPtr and returns 0 on success or -1 on failure
long proto_ptr(long pid, Proto* *ptrPtr); long proto_ptr(long pid, Proto* *ptrPtr);
+11 -2
View File
@@ -19,12 +19,14 @@
WRAP_WATCOM_FFUNC4(long, _word_wrap, const char*, text, int, maxWidth, DWORD*, buf, BYTE*, count) WRAP_WATCOM_FFUNC4(long, _word_wrap, const char*, text, int, maxWidth, DWORD*, buf, BYTE*, count)
WRAP_WATCOM_FFUNC3(void, correctFidForRemovedItem, GameObject*, critter, GameObject*, item, long, slotFlag) WRAP_WATCOM_FFUNC3(void, correctFidForRemovedItem, GameObject*, critter, GameObject*, item, long, slotFlag)
WRAP_WATCOM_FFUNC7(long, createWindow, const char*, winName, DWORD, x, DWORD, y, DWORD, width, DWORD, height, long, color, long, flags) WRAP_WATCOM_FFUNC7(long, createWindow, const char*, winName, DWORD, x, DWORD, y, DWORD, width, DWORD, height, long, color, long, flags)
WRAP_WATCOM_FFUNC4(long, determine_to_hit, GameObject*, source, GameObject*, target, long, bodyPart, long, hitMode)
WRAP_WATCOM_FFUNC3(void, display_inventory, long, inventoryOffset, long, visibleOffset, long, mode) WRAP_WATCOM_FFUNC3(void, display_inventory, long, inventoryOffset, long, visibleOffset, long, mode)
WRAP_WATCOM_FFUNC4(void, display_target_inventory, long, inventoryOffset, long, visibleOffset, DWORD*, targetInventory, long, mode) WRAP_WATCOM_FFUNC4(void, display_target_inventory, long, inventoryOffset, long, visibleOffset, DWORD*, targetInventory, long, mode)
WRAP_WATCOM_FFUNC3(FrmFrameData*, frame_ptr, FrmHeaderData*, frm, long, frame, long, direction) WRAP_WATCOM_FFUNC3(FrmFrameData*, frame_ptr, FrmHeaderData*, frm, long, frame, long, direction)
WRAP_WATCOM_FFUNC3(void, intface_update_items, long, animate, long, modeLeft,long, modeRight) WRAP_WATCOM_FFUNC3(void, intface_update_items, long, animate, long, modeLeft,long, modeRight)
WRAP_WATCOM_FFUNC3(GameObject*, inven_find_type, GameObject*, critter, long, itemType, DWORD*, buf) WRAP_WATCOM_FFUNC3(GameObject*, inven_find_type, GameObject*, critter, long, itemType, DWORD*, buf)
WRAP_WATCOM_FFUNC3(long, item_add_force, GameObject*, critter, GameObject*, item, long, count) WRAP_WATCOM_FFUNC3(long, item_add_force, GameObject*, critter, GameObject*, item, long, count)
WRAP_WATCOM_FFUNC3(long, item_w_mp_cost, GameObject*, source, long, hitMode, long, isCalled)
WRAP_WATCOM_FFUNC7(void, make_straight_path_func, GameObject*, objFrom, DWORD, tileFrom, DWORD, tileTo, void*, rotationPtr, DWORD*, result, long, flags, void*, func) WRAP_WATCOM_FFUNC7(void, make_straight_path_func, GameObject*, objFrom, DWORD, tileFrom, DWORD, tileTo, void*, rotationPtr, DWORD*, result, long, flags, void*, func)
WRAP_WATCOM_FFUNC3(long, message_find, DWORD*, msgFile, long, msgNumber, DWORD*, outBuf) WRAP_WATCOM_FFUNC3(long, message_find, DWORD*, msgFile, long, msgNumber, DWORD*, outBuf)
WRAP_WATCOM_FFUNC4(long, mouse_click_in, long, x, long, y, long, x_end, long, y_end) WRAP_WATCOM_FFUNC4(long, mouse_click_in, long, x, long, y, long, x_end, long, y_end)
@@ -33,6 +35,8 @@ WRAP_WATCOM_FFUNC4(long, obj_move_to_tile, GameObject*, object, long, tile, long
WRAP_WATCOM_FFUNC3(long, obj_new_sid_inst, GameObject*, object, long, sType, long, scriptIndex) WRAP_WATCOM_FFUNC3(long, obj_new_sid_inst, GameObject*, object, long, sType, long, scriptIndex)
WRAP_WATCOM_FFUNC3(long, object_under_mouse, long, crSwitch, long, inclDude, long, elevation) WRAP_WATCOM_FFUNC3(long, object_under_mouse, long, crSwitch, long, inclDude, long, elevation)
WRAP_WATCOM_FFUNC4(void, register_object_call, long*, target, long*, source, void*, func, long, delay) WRAP_WATCOM_FFUNC4(void, register_object_call, long*, target, long*, source, void*, func, long, delay)
WRAP_WATCOM_FFUNC4(long, register_object_move_to_object, GameObject*, source, GameObject*, target, long, distance, long, delay)
WRAP_WATCOM_FFUNC4(long, register_object_run_to_object, GameObject*, source, GameObject*, target, long, distance, long, delay)
WRAP_WATCOM_FFUNC3(long, scr_get_local_var, long, sid, long, varId, long*, value) WRAP_WATCOM_FFUNC3(long, scr_get_local_var, long, sid, long, varId, long*, value)
WRAP_WATCOM_FFUNC3(long, scr_set_local_var, long, sid, long, varId, long, value) WRAP_WATCOM_FFUNC3(long, scr_set_local_var, long, sid, long, varId, long, value)
WRAP_WATCOM_FFUNC3(long, tile_num_in_direction, long, tile, long, rotation,long, distance) WRAP_WATCOM_FFUNC3(long, tile_num_in_direction, long, tile, long, rotation,long, distance)
@@ -84,8 +88,10 @@ WRAP_WATCOM_FUNC2(void, intface_update_move_points, long, ap, long, freeAP)
WRAP_WATCOM_FUNC0(void, intface_use_item) WRAP_WATCOM_FUNC0(void, intface_use_item)
WRAP_WATCOM_FUNC2(long, inven_unwield, GameObject*, critter, long, slot) WRAP_WATCOM_FUNC2(long, inven_unwield, GameObject*, critter, long, slot)
WRAP_WATCOM_FUNC0(long, is_pc_sneak_working) WRAP_WATCOM_FUNC0(long, is_pc_sneak_working)
WRAP_WATCOM_FUNC2(long, is_within_perception, GameObject*, source, GameObject*, target)
WRAP_WATCOM_FUNC1(long, item_c_curr_size, GameObject*, critter) WRAP_WATCOM_FUNC1(long, item_c_curr_size, GameObject*, critter)
WRAP_WATCOM_FUNC1(long, item_caps_total, GameObject*, object) WRAP_WATCOM_FUNC1(long, item_caps_total, GameObject*, object)
WRAP_WATCOM_FUNC2(GameObject*, item_hit_with, GameObject*, critter, long, hitMode)
WRAP_WATCOM_FUNC1(long, item_size, GameObject*, item) WRAP_WATCOM_FUNC1(long, item_size, GameObject*, item)
WRAP_WATCOM_FUNC1(long, item_total_cost, GameObject*, object) WRAP_WATCOM_FUNC1(long, item_total_cost, GameObject*, object)
WRAP_WATCOM_FUNC1(long, item_total_weight, GameObject*, object) WRAP_WATCOM_FUNC1(long, item_total_weight, GameObject*, object)
@@ -98,8 +104,10 @@ WRAP_WATCOM_FUNC1(long, item_w_dam_div, GameObject*, item)
WRAP_WATCOM_FUNC1(long, item_w_dam_mult, GameObject*, item) WRAP_WATCOM_FUNC1(long, item_w_dam_mult, GameObject*, item)
WRAP_WATCOM_FUNC1(long, item_w_dr_adjust, GameObject*, item) WRAP_WATCOM_FUNC1(long, item_w_dr_adjust, GameObject*, item)
WRAP_WATCOM_FUNC1(long, item_w_max_ammo, GameObject*, item) WRAP_WATCOM_FUNC1(long, item_w_max_ammo, GameObject*, item)
WRAP_WATCOM_FUNC2(long, item_w_range, GameObject*, critter, long, hitMode)
WRAP_WATCOM_FUNC2(long, item_w_reload, GameObject*, weapon, GameObject*, ammo) WRAP_WATCOM_FUNC2(long, item_w_reload, GameObject*, weapon, GameObject*, ammo)
WRAP_WATCOM_FUNC1(long, item_w_rounds, GameObject*, item) WRAP_WATCOM_FUNC1(long, item_w_rounds, GameObject*, item)
WRAP_WATCOM_FUNC2(long, item_w_subtype, GameObject*, item, long, hitMode)
WRAP_WATCOM_FUNC1(long, item_weight, GameObject*, item) WRAP_WATCOM_FUNC1(long, item_weight, GameObject*, item)
// returns light level at given tile // returns light level at given tile
WRAP_WATCOM_FUNC2(long, light_get_tile, long, elevation, long, tileNum) WRAP_WATCOM_FUNC2(long, light_get_tile, long, elevation, long, tileNum)
@@ -114,6 +122,7 @@ WRAP_WATCOM_FUNC0(long, new_obj_id)
// calculates bounding box (rectangle) for a given object // calculates bounding box (rectangle) for a given object
WRAP_WATCOM_FUNC2(void, obj_bound, GameObject*, object, BoundRect*, boundRect) WRAP_WATCOM_FUNC2(void, obj_bound, GameObject*, object, BoundRect*, boundRect)
WRAP_WATCOM_FUNC1(long, obj_destroy, GameObject*, object) WRAP_WATCOM_FUNC1(long, obj_destroy, GameObject*, object)
WRAP_WATCOM_FUNC2(long, obj_dist, GameObject*, source, GameObject*, target)
WRAP_WATCOM_FUNC2(long, obj_erase_object, GameObject*, object, BoundRect*, boundRect) WRAP_WATCOM_FUNC2(long, obj_erase_object, GameObject*, object, BoundRect*, boundRect)
WRAP_WATCOM_FUNC0(GameObject*, obj_find_first) WRAP_WATCOM_FUNC0(GameObject*, obj_find_first)
WRAP_WATCOM_FUNC0(GameObject*, obj_find_next) WRAP_WATCOM_FUNC0(GameObject*, obj_find_next)
@@ -130,6 +139,8 @@ WRAP_WATCOM_FUNC0(void, process_bk)
WRAP_WATCOM_FUNC0(void, proto_dude_update_gender) WRAP_WATCOM_FUNC0(void, proto_dude_update_gender)
WRAP_WATCOM_FUNC2(long*, queue_find_first, GameObject*, object, long, qType) WRAP_WATCOM_FUNC2(long*, queue_find_first, GameObject*, object, long, qType)
WRAP_WATCOM_FUNC2(long*, queue_find_next, GameObject*, object, long, qType) WRAP_WATCOM_FUNC2(long*, queue_find_next, GameObject*, object, long, qType)
WRAP_WATCOM_FUNC1(long, register_begin, long, regType)
WRAP_WATCOM_FUNC0(long, register_end)
WRAP_WATCOM_FUNC3(long, register_object_animate, GameObject*, object, long, anim, long, delay) WRAP_WATCOM_FUNC3(long, register_object_animate, GameObject*, object, long, anim, long, delay)
WRAP_WATCOM_FUNC3(long, register_object_animate_and_hide, GameObject*, object, long, anim, long, delay) WRAP_WATCOM_FUNC3(long, register_object_animate_and_hide, GameObject*, object, long, anim, long, delay)
// WRAP_WATCOM_FUNC3(long, register_object_animate_and_move_straight_, GameObject*, object; // WRAP_WATCOM_FUNC3(long, register_object_animate_and_move_straight_, GameObject*, object;
@@ -144,13 +155,11 @@ WRAP_WATCOM_FUNC1(long, register_object_inc_rotation, GameObject*, object)
WRAP_WATCOM_FUNC3(long, register_object_light, GameObject*, object, long, lightRadius, long, delay) WRAP_WATCOM_FUNC3(long, register_object_light, GameObject*, object, long, lightRadius, long, delay)
// WRAP_WATCOM_FUNC3(long, register_object_move_on_stairs_, GameObject*, object; // WRAP_WATCOM_FUNC3(long, register_object_move_on_stairs_, GameObject*, object;
// WRAP_WATCOM_FUNC3(long, register_object_move_straight_to_tile_, GameObject*, object; // WRAP_WATCOM_FUNC3(long, register_object_move_straight_to_tile_, GameObject*, object;
// WRAP_WATCOM_FUNC3(long, register_object_move_to_object_, GameObject*, object;
// WRAP_WATCOM_FUNC3(long, register_object_move_to_tile_, GameObject*, object; // WRAP_WATCOM_FUNC3(long, register_object_move_to_tile_, GameObject*, object;
// WRAP_WATCOM_FUNC3(long, register_object_must_call_, GameObject*, object; // WRAP_WATCOM_FUNC3(long, register_object_must_call_, GameObject*, object;
WRAP_WATCOM_FUNC1(long, register_object_must_erase, GameObject*, object) WRAP_WATCOM_FUNC1(long, register_object_must_erase, GameObject*, object)
// WRAP_WATCOM_FUNC3(long, register_object_outline_, GameObject*, object; // WRAP_WATCOM_FUNC3(long, register_object_outline_, GameObject*, object;
// WRAP_WATCOM_FUNC3(long, register_object_play_sfx_, GameObject*, object; // WRAP_WATCOM_FUNC3(long, register_object_play_sfx_, GameObject*, object;
// WRAP_WATCOM_FUNC3(long, register_object_run_to_object_, GameObject*, object;
// WRAP_WATCOM_FUNC3(long, register_object_run_to_tile_, GameObject*, object; // WRAP_WATCOM_FUNC3(long, register_object_run_to_tile_, GameObject*, object;
WRAP_WATCOM_FUNC3(long, register_object_take_out, GameObject*, object, long, holdFrameId, long, nothing) WRAP_WATCOM_FUNC3(long, register_object_take_out, GameObject*, object, long, holdFrameId, long, nothing)
WRAP_WATCOM_FUNC3(long, register_object_turn_towards, GameObject*, object, long, tileNum, long, nothing) WRAP_WATCOM_FUNC3(long, register_object_turn_towards, GameObject*, object, long, tileNum, long, nothing)
+2 -2
View File
@@ -373,6 +373,7 @@ struct UnlistedFrm {
} }
}; };
//for holding a message
#pragma pack(1) #pragma pack(1)
struct MessageNode { struct MessageNode {
long number; long number;
@@ -424,8 +425,7 @@ struct CritInfo {
}; };
#pragma pack(1) #pragma pack(1)
struct SkillInfo struct SkillInfo {
{
const char* name; const char* name;
const char* description; const char* description;
long attr; long attr;
+3 -1
View File
@@ -277,6 +277,8 @@
#define FO_VAR_DARK_GREY_Color 0x6A59D8 #define FO_VAR_DARK_GREY_Color 0x6A59D8
#define FO_VAR_DarkGreenColor 0x6A3A90 #define FO_VAR_DarkGreenColor 0x6A3A90
#define FO_VAR_DarkGreenGreyColor 0x6A3DF1 #define FO_VAR_DarkGreenGreyColor 0x6A3DF1
#define FO_VAR_DarkRedColor 0x6AA8D0
#define FO_VAR_DarkYellowColor 0x6AB472
#define FO_VAR_DullPinkColor 0x6AB718 #define FO_VAR_DullPinkColor 0x6AB718
#define FO_VAR_GoodColor 0x6AB4EF #define FO_VAR_GoodColor 0x6AB4EF
#define FO_VAR_GreenColor 0x6A3CB0 #define FO_VAR_GreenColor 0x6A3CB0
@@ -285,4 +287,4 @@
#define FO_VAR_PeanutButter 0x6A82F3 #define FO_VAR_PeanutButter 0x6A82F3
#define FO_VAR_RedColor 0x6AB4D0 #define FO_VAR_RedColor 0x6AB4D0
#define FO_VAR_WhiteColor 0x6AB8CF #define FO_VAR_WhiteColor 0x6AB8CF
#define FO_VAR_YellowColor 0x6AB8BB #define FO_VAR_YellowColor 0x6AB8BB // Light
+32 -31
View File
@@ -17,6 +17,7 @@
*/ */
#define DIRECTINPUT_VERSION 0x0700 #define DIRECTINPUT_VERSION 0x0700
#include <math.h> #include <math.h>
#include <dinput.h> #include <dinput.h>
#include <queue> #include <queue>
@@ -56,7 +57,7 @@ static int mouseY;
static DWORD forcingGraphicsRefresh = 0; static DWORD forcingGraphicsRefresh = 0;
void _stdcall ForceGraphicsRefresh(DWORD d) { void __stdcall ForceGraphicsRefresh(DWORD d) {
forcingGraphicsRefresh = (d == 0) ? 0 : 1; forcingGraphicsRefresh = (d == 0) ? 0 : 1;
} }
@@ -107,7 +108,7 @@ void FlushInputBuffer() {
__asm call fo::funcoffs::kb_clear_; __asm call fo::funcoffs::kb_clear_;
} }
DWORD _stdcall KeyDown(DWORD key) { DWORD __stdcall KeyDown(DWORD key) {
if ((key & 0x80000000) > 0) { // special flag to check by VK code directly if ((key & 0x80000000) > 0) { // special flag to check by VK code directly
return GetAsyncKeyState(key & 0xFFFF) & 0x8000; return GetAsyncKeyState(key & 0xFFFF) & 0x8000;
} }
@@ -125,7 +126,7 @@ DWORD _stdcall KeyDown(DWORD key) {
} }
} }
void _stdcall TapKey(DWORD key) { void __stdcall TapKey(DWORD key) {
DIDEVICEOBJECTDATA data; DIDEVICEOBJECTDATA data;
data.dwTimeStamp = 0; data.dwTimeStamp = 0;
data.dwSequence = 0; data.dwSequence = 0;
@@ -155,15 +156,15 @@ public:
} }
/*** IUnknown methods ***/ /*** IUnknown methods ***/
HRESULT _stdcall QueryInterface(REFIID riid, LPVOID * ppvObj) { HRESULT __stdcall QueryInterface(REFIID riid, LPVOID * ppvObj) {
return RealDevice->QueryInterface(riid, ppvObj); return RealDevice->QueryInterface(riid, ppvObj);
} }
ULONG _stdcall AddRef(void) { ULONG __stdcall AddRef(void) {
return ++Refs; return ++Refs;
} }
ULONG _stdcall Release(void) { ULONG __stdcall Release(void) {
if (--Refs == 0) { if (--Refs == 0) {
RealDevice->Release(); RealDevice->Release();
delete this; delete this;
@@ -174,32 +175,32 @@ public:
} }
/*** IDirectInputDevice8A methods ***/ /*** IDirectInputDevice8A methods ***/
HRESULT _stdcall GetCapabilities(LPDIDEVCAPS a) { HRESULT __stdcall GetCapabilities(LPDIDEVCAPS a) {
return RealDevice->GetCapabilities(a); return RealDevice->GetCapabilities(a);
} }
HRESULT _stdcall EnumObjects(LPDIENUMDEVICEOBJECTSCALLBACKA a, LPVOID b, DWORD c) { HRESULT __stdcall EnumObjects(LPDIENUMDEVICEOBJECTSCALLBACKA a, LPVOID b, DWORD c) {
return RealDevice->EnumObjects(a, b, c); return RealDevice->EnumObjects(a, b, c);
} }
HRESULT _stdcall GetProperty(REFGUID a, DIPROPHEADER* b) { HRESULT __stdcall GetProperty(REFGUID a, DIPROPHEADER* b) {
return RealDevice->GetProperty(a, b); return RealDevice->GetProperty(a, b);
} }
HRESULT _stdcall SetProperty(REFGUID a, const DIPROPHEADER* b) { HRESULT __stdcall SetProperty(REFGUID a, const DIPROPHEADER* b) {
return RealDevice->SetProperty(a, b); return RealDevice->SetProperty(a, b);
} }
HRESULT _stdcall Acquire(void) { HRESULT __stdcall Acquire(void) {
return RealDevice->Acquire(); return RealDevice->Acquire();
} }
HRESULT _stdcall Unacquire(void) { HRESULT __stdcall Unacquire(void) {
return RealDevice->Unacquire(); return RealDevice->Unacquire();
} }
// Only called for the mouse // Only called for the mouse
HRESULT _stdcall GetDeviceState(DWORD a, LPVOID b) { HRESULT __stdcall GetDeviceState(DWORD a, LPVOID b) {
if (forcingGraphicsRefresh) RefreshGraphics(); if (forcingGraphicsRefresh) RefreshGraphics();
if (DeviceType != kDeviceType_MOUSE) { if (DeviceType != kDeviceType_MOUSE) {
return RealDevice->GetDeviceState(a, b); return RealDevice->GetDeviceState(a, b);
@@ -269,7 +270,7 @@ public:
} }
// Only called for the keyboard (dxinput_read_keyboard_buffer_ called at 0x4E06AB) // Only called for the keyboard (dxinput_read_keyboard_buffer_ called at 0x4E06AB)
HRESULT _stdcall GetDeviceData(DWORD a, DIDEVICEOBJECTDATA* buf, DWORD* count, DWORD d) { // buf - DirectInputKeyboardBuffer (0x6B2560) HRESULT __stdcall GetDeviceData(DWORD a, DIDEVICEOBJECTDATA* buf, DWORD* count, DWORD d) { // buf - DirectInputKeyboardBuffer (0x6B2560)
if (DeviceType != kDeviceType_KEYBOARD) { if (DeviceType != kDeviceType_KEYBOARD) {
return RealDevice->GetDeviceData(a, buf, count, d); return RealDevice->GetDeviceData(a, buf, count, d);
} }
@@ -304,35 +305,35 @@ public:
return DI_OK; return DI_OK;
} }
HRESULT _stdcall SetDataFormat(const DIDATAFORMAT* a) { HRESULT __stdcall SetDataFormat(const DIDATAFORMAT* a) {
if (formatLock && oldFormat.dwSize) return RealDevice->SetDataFormat(&oldFormat); if (formatLock && oldFormat.dwSize) return RealDevice->SetDataFormat(&oldFormat);
memcpy(&oldFormat, a, sizeof(DIDATAFORMAT)); memcpy(&oldFormat, a, sizeof(DIDATAFORMAT));
return RealDevice->SetDataFormat(a); return RealDevice->SetDataFormat(a);
} }
HRESULT _stdcall SetEventNotification(HANDLE a) { HRESULT __stdcall SetEventNotification(HANDLE a) {
return RealDevice->SetEventNotification(a); return RealDevice->SetEventNotification(a);
} }
HRESULT _stdcall SetCooperativeLevel(HWND a, DWORD b) { HRESULT __stdcall SetCooperativeLevel(HWND a, DWORD b) {
if (DeviceType == kDeviceType_KEYBOARD && backgroundKeyboard) b = DISCL_BACKGROUND | DISCL_NONEXCLUSIVE; if (DeviceType == kDeviceType_KEYBOARD && backgroundKeyboard) b = DISCL_BACKGROUND | DISCL_NONEXCLUSIVE;
if (DeviceType == kDeviceType_MOUSE && backgroundMouse) b = DISCL_BACKGROUND | DISCL_NONEXCLUSIVE; if (DeviceType == kDeviceType_MOUSE && backgroundMouse) b = DISCL_BACKGROUND | DISCL_NONEXCLUSIVE;
return RealDevice->SetCooperativeLevel(a, b); return RealDevice->SetCooperativeLevel(a, b);
} }
HRESULT _stdcall GetObjectInfo(LPDIDEVICEOBJECTINSTANCEA a, DWORD b, DWORD c) { HRESULT __stdcall GetObjectInfo(LPDIDEVICEOBJECTINSTANCEA a, DWORD b, DWORD c) {
return RealDevice->GetObjectInfo(a, b, c); return RealDevice->GetObjectInfo(a, b, c);
} }
HRESULT _stdcall GetDeviceInfo(LPDIDEVICEINSTANCEA a) { HRESULT __stdcall GetDeviceInfo(LPDIDEVICEINSTANCEA a) {
return RealDevice->GetDeviceInfo(a); return RealDevice->GetDeviceInfo(a);
} }
HRESULT _stdcall RunControlPanel(HWND a, DWORD b) { HRESULT __stdcall RunControlPanel(HWND a, DWORD b) {
return RealDevice->RunControlPanel(a, b); return RealDevice->RunControlPanel(a, b);
} }
HRESULT _stdcall Initialize(HINSTANCE a, DWORD b, REFGUID c) { HRESULT __stdcall Initialize(HINSTANCE a, DWORD b, REFGUID c) {
return RealDevice->Initialize(a, b, c); return RealDevice->Initialize(a, b, c);
} }
@@ -352,15 +353,15 @@ public:
} }
/*** IUnknown methods ***/ /*** IUnknown methods ***/
HRESULT _stdcall QueryInterface(REFIID riid, LPVOID* ppvObj) { HRESULT __stdcall QueryInterface(REFIID riid, LPVOID* ppvObj) {
return RealInput->QueryInterface(riid, ppvObj); return RealInput->QueryInterface(riid, ppvObj);
} }
ULONG _stdcall AddRef(void) { ULONG __stdcall AddRef(void) {
return ++Refs; return ++Refs;
} }
ULONG _stdcall Release(void) { ULONG __stdcall Release(void) {
if (--Refs == 0) { if (--Refs == 0) {
RealInput->Release(); RealInput->Release();
delete this; delete this;
@@ -371,7 +372,7 @@ public:
} }
/*** IDirectInput8A methods ***/ /*** IDirectInput8A methods ***/
HRESULT _stdcall CreateDevice(REFGUID r, IDirectInputDeviceA** device, IUnknown* unused) { HRESULT __stdcall CreateDevice(REFGUID r, IDirectInputDeviceA** device, IUnknown* unused) {
GUID GUID_SysMouse = { 0x6F1D2B60, 0xD5A0, 0x11CF, { 0xBF, 0xC7, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00} }; GUID GUID_SysMouse = { 0x6F1D2B60, 0xD5A0, 0x11CF, { 0xBF, 0xC7, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00} };
GUID GUID_SysKeyboard = { 0x6F1D2B61, 0xD5A0, 0x11CF, { 0xBF, 0xC7, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00} }; GUID GUID_SysKeyboard = { 0x6F1D2B61, 0xD5A0, 0x11CF, { 0xBF, 0xC7, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00} };
@@ -398,19 +399,19 @@ public:
} }
} }
HRESULT _stdcall EnumDevices(DWORD a, LPDIENUMDEVICESCALLBACKA b, void* c, DWORD d) { HRESULT __stdcall EnumDevices(DWORD a, LPDIENUMDEVICESCALLBACKA b, void* c, DWORD d) {
return RealInput->EnumDevices(a, b, c, d); return RealInput->EnumDevices(a, b, c, d);
} }
HRESULT _stdcall GetDeviceStatus(REFGUID r) { HRESULT __stdcall GetDeviceStatus(REFGUID r) {
return RealInput->GetDeviceStatus(r); return RealInput->GetDeviceStatus(r);
} }
HRESULT _stdcall RunControlPanel(HWND a, DWORD b) { HRESULT __stdcall RunControlPanel(HWND a, DWORD b) {
return RealInput->RunControlPanel(a, b); return RealInput->RunControlPanel(a, b);
} }
HRESULT _stdcall Initialize(HINSTANCE a, DWORD b) { HRESULT __stdcall Initialize(HINSTANCE a, DWORD b) {
return RealInput->Initialize(a, b); return RealInput->Initialize(a, b);
} }
}; };
@@ -439,10 +440,10 @@ inline void InitInputFeatures() {
} }
typedef HRESULT (_stdcall *DInputCreateProc)(HINSTANCE a,DWORD b,IDirectInputA** c,IUnknown* d); typedef HRESULT (__stdcall *DInputCreateProc)(HINSTANCE a,DWORD b,IDirectInputA** c,IUnknown* d);
// This should be in global namespace // This should be in global namespace
HRESULT _stdcall FakeDirectInputCreate(HINSTANCE a, DWORD b, IDirectInputA** c, IUnknown* d) { HRESULT __stdcall FakeDirectInputCreate(HINSTANCE a, DWORD b, IDirectInputA** c, IUnknown* d) {
HMODULE dinput = LoadLibraryA("dinput.dll"); HMODULE dinput = LoadLibraryA("dinput.dll");
if (!dinput || dinput == INVALID_HANDLE_VALUE) return -1; if (!dinput || dinput == INVALID_HANDLE_VALUE) return -1;
DInputCreateProc proc = (DInputCreateProc)GetProcAddress(dinput, "DirectInputCreateA"); DInputCreateProc proc = (DInputCreateProc)GetProcAddress(dinput, "DirectInputCreateA");
+3 -3
View File
@@ -32,8 +32,8 @@ void SetMDown(bool down, bool right);
void SetMPos(int x, int y); void SetMPos(int x, int y);
void FlushInputBuffer(); void FlushInputBuffer();
DWORD _stdcall KeyDown(DWORD key); DWORD __stdcall KeyDown(DWORD key);
void _stdcall TapKey(DWORD key); void __stdcall TapKey(DWORD key);
typedef Delegate<DWORD, bool> KeyPressedDelegate; typedef Delegate<DWORD, bool> KeyPressedDelegate;
typedef Delegate<DWORD, bool> MouseClickedDelegate; typedef Delegate<DWORD, bool> MouseClickedDelegate;
@@ -44,7 +44,7 @@ Delegate<>& OnInputLoop();
void GetMouse(int* x, int* y); void GetMouse(int* x, int* y);
void _stdcall ForceGraphicsRefresh(DWORD); void __stdcall ForceGraphicsRefresh(DWORD);
#define DIK_ESCAPE 0x01 #define DIK_ESCAPE 0x01
#define DIK_1 0x02 #define DIK_1 0x02
+2 -2
View File
@@ -11,13 +11,13 @@ ModuleManager::ModuleManager() {
} }
ModuleManager::~ModuleManager() { ModuleManager::~ModuleManager() {
for (auto it = _modules.cbegin(); it != _modules.cend(); it++) { for (auto it = _modules.cbegin(); it != _modules.cend(); ++it) {
(*it)->exit(); (*it)->exit();
} }
} }
void ModuleManager::initAll() { void ModuleManager::initAll() {
for (auto it = _modules.cbegin(); it != _modules.cend(); it++) { for (auto it = _modules.cbegin(); it != _modules.cend(); ++it) {
dlog_f("Initializing module %s...\n", DL_INIT, (*it)->name()); dlog_f("Initializing module %s...\n", DL_INIT, (*it)->name());
(*it)->init(); (*it)->init();
} }
+180 -8
View File
@@ -21,6 +21,8 @@
#include "..\main.h" #include "..\main.h"
#include "..\FalloutEngine\Fallout2.h" #include "..\FalloutEngine\Fallout2.h"
#include "HookScripts\CombatHS.h"
#include "AI.h" #include "AI.h"
namespace sfall namespace sfall
@@ -32,6 +34,24 @@ using namespace Fields;
static std::unordered_map<fo::GameObject*, fo::GameObject*> targets; static std::unordered_map<fo::GameObject*, fo::GameObject*> targets;
static std::unordered_map<fo::GameObject*, fo::GameObject*> sources; static std::unordered_map<fo::GameObject*, fo::GameObject*> sources;
fo::GameObject* AI::sf_check_critters_in_lof(fo::GameObject* object, DWORD checkTile, DWORD team) {
if (object && object->Type() == ObjType::OBJ_TYPE_CRITTER && object->critter.teamNum != team) { // not friendly fire
if (object->tile == checkTile) return nullptr;
fo::GameObject* obj = nullptr; // continue checking the line of fire from object to checkTile
fo::func::make_straight_path_func(object, object->tile, checkTile, 0, (DWORD*)&obj, 32, (void*)fo::funcoffs::obj_shoot_blocking_at_);
if (!sf_check_critters_in_lof(obj, checkTile, team)) return nullptr;
}
return object;
}
// Returns the friendly critter that is in the line of fire
fo::GameObject* AI::CheckFriendlyFire(fo::GameObject* target, fo::GameObject* attacker) {
fo::GameObject* object = nullptr;
fo::func::make_straight_path_func(attacker, attacker->tile, target->tile, 0, (DWORD*)&object, 32, (void*)fo::funcoffs::obj_shoot_blocking_at_);
object = sf_check_critters_in_lof(object, target->tile, attacker->critter.teamNum);
return (!object || object->TypeFid() == fo::ObjType::OBJ_TYPE_CRITTER) ? object : nullptr; // 0 if there are no friendly critters
}
static void __declspec(naked) ai_try_attack_hook_FleeFix() { static void __declspec(naked) ai_try_attack_hook_FleeFix() {
__asm { __asm {
or byte ptr [esi + combatState], 8; // set new 'ReTarget' flag or byte ptr [esi + combatState], 8; // set new 'ReTarget' flag
@@ -40,7 +60,7 @@ static void __declspec(naked) ai_try_attack_hook_FleeFix() {
} }
static void __declspec(naked) combat_ai_hook_FleeFix() { static void __declspec(naked) combat_ai_hook_FleeFix() {
static const DWORD combat_ai_hook_flee_Ret = 0x42B22F; static const DWORD combat_ai_hook_flee_Ret = 0x42B206;
__asm { __asm {
test byte ptr [ebp], 8; // 'ReTarget' flag (critter.combat_state) test byte ptr [ebp], 8; // 'ReTarget' flag (critter.combat_state)
jnz reTarget; jnz reTarget;
@@ -152,7 +172,23 @@ skip:
} }
} }
static DWORD RetryCombatMinAP; static void __declspec(naked) ai_danger_source_hack_pm_newfind() {
__asm {
mov ecx, [ebp + 0x18]; // source combat_data.who_hit_me
test ecx, ecx;
jnz hasTarget;
retn;
hasTarget:
test [ecx + damageFlags], DAM_DEAD;
jz isNotDead;
xor ecx, ecx;
isNotDead:
mov dword ptr [ebp + 0x18], 0; // combat_data.who_hit_me (engine code)
retn;
}
}
static long RetryCombatMinAP;
static void __declspec(naked) RetryCombatHook() { static void __declspec(naked) RetryCombatHook() {
static DWORD RetryCombatLastAP = 0; static DWORD RetryCombatLastAP = 0;
@@ -189,7 +225,7 @@ static long __fastcall sf_ai_weapon_reload(fo::GameObject* weapon, fo::GameObjec
while (ammo) { while (ammo) {
result = fo::func::item_w_reload(weapon, ammo); result = fo::func::item_w_reload(weapon, ammo);
if (result != 0) break; // 1 - reload done, -1 - can't reload if (result != 0) return result; // 1 - reload done, -1 - can't reload
if (!proto) { if (!proto) {
proto = fo::GetProto(weapon->protoId); proto = fo::GetProto(weapon->protoId);
@@ -209,7 +245,7 @@ static long __fastcall sf_ai_weapon_reload(fo::GameObject* weapon, fo::GameObjec
} }
} }
} }
if (!result && _ammo != ammo) { if (_ammo != ammo) {
fo::func::obj_destroy(ammo); fo::func::obj_destroy(ammo);
return 1; // notifies the engine that the ammo has already been destroyed return 1; // notifies the engine that the ammo has already been destroyed
} }
@@ -231,6 +267,112 @@ skip:
} }
} }
static long __fastcall CheckWeaponRangeAndApCost(fo::GameObject* source, fo::GameObject* target) {
long weaponRange = fo::func::item_w_range(source, fo::ATKTYPE_RWEAPON_SECONDARY);
long targetDist = fo::func::obj_dist(source, target);
if (targetDist > weaponRange) return 0; // don't use secondary mode
return (source->critter.movePoints >= sf_item_w_mp_cost(source, fo::ATKTYPE_RWEAPON_SECONDARY, 0)); // 1 - allow secondary mode
}
static void __declspec(naked) ai_pick_hit_mode_hook() {
__asm {
call fo::funcoffs::caiHasWeapPrefType_;
test eax, eax;
jnz evaluation;
retn;
evaluation:
mov edx, edi;
mov ecx, esi;
jmp CheckWeaponRangeAndApCost;
}
}
static void __declspec(naked) ai_danger_source_hook() {
__asm {
call fo::funcoffs::combat_check_bad_shot_;
cmp dword ptr [esp + 56], 0x42B235 + 5; // called from combat_ai_
je fix;
retn;
fix: // check result
cmp eax, 1; // exception: 1 - no ammo
setg al; // set 0 for result OK
retn;
}
}
static void __declspec(naked) cai_perform_distance_prefs_hack() {
__asm {
mov ebx, eax; // current distance to target
mov ecx, esi;
push 0; // no called shot
mov edx, ATKTYPE_RWEAPON_PRIMARY;
call sf_item_w_mp_cost;
mov edx, [esi + movePoints];
sub edx, eax; // ap - cost = free AP's
jle moveAway; // <= 0
lea edx, [edx + ebx - 1];
cmp edx, 5; // minimum threshold distance
jge skipMove; // distance >= 5?
// check combat rating
mov eax, esi;
call fo::funcoffs::combatai_rating_;
mov edx, eax; // source rating
mov eax, edi;
call fo::funcoffs::combatai_rating_;
cmp eax, edx; // target vs source rating
jl skipMove; // target rating is low
moveAway:
mov ebx, 10; // move away max distance
retn;
skipMove:
xor ebx, ebx; // skip moving away at the beginning of the turn
retn;
}
}
static void __declspec(naked) ai_move_away_hook() {
static const DWORD ai_move_away_hook_Ret = 0x4289DA;
__asm {
test ebx, ebx;
jl fix; // distance arg < 0
jmp fo::funcoffs::ai_cap_;
fix:
neg ebx;
mov eax, [esi + movePoints]; // Current Action Points
cmp ebx, eax;
cmovg ebx, eax; // if (distance > ap) dist = ap
add esp, 4;
jmp ai_move_away_hook_Ret;
}
}
////////////////////////////////////////////////////////////////////////////////
static long __fastcall RollFriendlyFire(fo::GameObject* target, fo::GameObject* attacker) {
if (AI::CheckFriendlyFire(target, attacker)) {
long dice = fo::func::roll_random(1, 10);
return (fo::func::stat_level(attacker, fo::STAT_iq) >= dice); // 1 - is friendly
}
return 0;
}
static void __declspec(naked) combat_safety_invalidate_weapon_func_hook_check() {
static const DWORD safety_invalidate_weapon_burst_friendly = 0x4216C9;
__asm {
pushadc;
mov ecx, esi; // target
call RollFriendlyFire;
test eax, eax;
jnz friendly;
popadc;
jmp fo::funcoffs::combat_ctd_init_;
friendly:
lea esp, [esp + 8 + 3 * 4];
jmp safety_invalidate_weapon_burst_friendly; // "Friendly was in the way!"
}
}
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
static void __fastcall CombatAttackHook(fo::GameObject* source, fo::GameObject* target) { static void __fastcall CombatAttackHook(fo::GameObject* source, fo::GameObject* target) {
@@ -271,8 +413,29 @@ void AI::init() {
0x42A970, 0x42AA56, // ai_try_attack_ 0x42A970, 0x42AA56, // ai_try_attack_
}); });
// Adds a check for the weapon range and the AP cost when AI is choosing weapon attack modes
HookCall(0x429F6D, ai_pick_hit_mode_hook);
/////////////////////// Combat AI behavior fixes /////////////////////// /////////////////////// Combat AI behavior fixes ///////////////////////
// Fix to reduce friendly fire in burst attacks
// Adds a check/roll for friendly critters in the line of fire when AI uses burst attacks
HookCall(0x421666, combat_safety_invalidate_weapon_func_hook_check);
// Fix for duplicate critters being added to the list of potential targets for AI
MakeCall(0x428E75, ai_find_attackers_hack_target2, 2);
MakeCall(0x428EB5, ai_find_attackers_hack_target3);
MakeCall(0x428EE5, ai_find_attackers_hack_target4, 1);
#ifndef NDEBUG
if (iniGetInt("Debugging", "AIBugFixes", 1, ::sfall::ddrawIni) == 0) return;
#endif
// Tweak for finding new targets for party members
// Save the current target in the "target1" variable and find other potential targets
MakeCall(0x429074, ai_danger_source_hack_pm_newfind);
SafeWrite16(0x429074 + 5, 0x47EB); // jmp 0x4290C2
// Fix to allow fleeing NPC to use drugs // Fix to allow fleeing NPC to use drugs
MakeCall(0x42B1DC, combat_ai_hack); MakeCall(0x42B1DC, combat_ai_hack);
// Fix for AI not checking minimum hp properly for using stimpaks (prevents premature fleeing) // Fix for AI not checking minimum hp properly for using stimpaks (prevents premature fleeing)
@@ -284,10 +447,19 @@ void AI::init() {
// Disable fleeing when NPC cannot move closer to target // Disable fleeing when NPC cannot move closer to target
BlockCall(0x42ADF6); // ai_try_attack_ BlockCall(0x42ADF6); // ai_try_attack_
// Fix for duplicate critters being added to the list of potential targets for AI // Fix AI target selection for combat_check_bad_shot_ function returning a no_ammo result
MakeCall(0x428E75, ai_find_attackers_hack_target2, 2); HookCalls(ai_danger_source_hook, {0x42903A, 0x42918A});
MakeCall(0x428EB5, ai_find_attackers_hack_target3);
MakeCall(0x428EE5, ai_find_attackers_hack_target4, 1); // Fix AI behavior for "Snipe" distance preference
// The attacker will try to shoot the target instead of always running away from it at the beginning of the turn
MakeCall(0x42B086, cai_perform_distance_prefs_hack);
// Fix for ai_move_away_ engine function not working correctly in cases when needing to move a distance away from the target
// now the function also takes the distance argument in a negative value for moving away at a distance
HookCall(0x4289A7, ai_move_away_hook);
// also patch combat_safety_invalidate_weapon_func_ for returning out_range argument in a negative value
SafeWrite8(0x421628, 0xD0); // sub edx, eax > sub eax, edx
SafeWrite16(0x42162A, 0xFF40); // lea eax, [edx+1] > lea eax, [eax-1]
} }
fo::GameObject* __stdcall AI::AIGetLastAttacker(fo::GameObject* target) { fo::GameObject* __stdcall AI::AIGetLastAttacker(fo::GameObject* target) {
+3
View File
@@ -30,6 +30,9 @@ public:
const char* name() { return "AI"; } const char* name() { return "AI"; }
void init(); void init();
static fo::GameObject* sf_check_critters_in_lof(fo::GameObject* object, DWORD checkTile, DWORD team);
static fo::GameObject* CheckFriendlyFire(fo::GameObject* target, fo::GameObject* attacker);
// TODO: use subscription instead // TODO: use subscription instead
static void __stdcall AICombatStart(); static void __stdcall AICombatStart();
static void __stdcall AICombatEnd(); static void __stdcall AICombatEnd();
+2 -2
View File
@@ -191,9 +191,9 @@ static DWORD __fastcall CheckSetSad(BYTE openFlag, DWORD valueMul) {
return result; return result;
} }
static const DWORD object_move_back0 = 0x417611;
static const DWORD object_move_back1 = 0x417616;
static void __declspec(naked) object_move_hack() { static void __declspec(naked) object_move_hack() {
static const DWORD object_move_back0 = 0x417611;
static const DWORD object_move_back1 = 0x417616;
__asm { __asm {
mov ecx, ds:[ecx + 0x3C]; // openFlag mov ecx, ds:[ecx + 0x3C]; // openFlag
mov edx, [esp + 0x4C - 0x20]; // valueMul mov edx, [esp + 0x4C - 0x20]; // valueMul
+5 -5
View File
@@ -61,9 +61,9 @@ static const DWORD bboxSlotAddr[] = {
0x4616F7, 0x46170F, 0x461736, 0x4616B1, 0x46151D, 0x4615B3 0x4616F7, 0x46170F, 0x461736, 0x4616B1, 0x46151D, 0x4615B3
}; };
static const DWORD DisplayBoxesRet1 = 0x4615A8;
static const DWORD DisplayBoxesRet2 = 0x4615BE;
static void __declspec(naked) DisplayBoxesHack() { static void __declspec(naked) DisplayBoxesHack() {
static const DWORD DisplayBoxesRet1 = 0x4615A8;
static const DWORD DisplayBoxesRet2 = 0x4615BE;
__asm { __asm {
mov edx, [boxText]; mov edx, [boxText];
xor ebx, ebx; xor ebx, ebx;
@@ -115,8 +115,8 @@ skip:
} }
} }
static const DWORD SetIndexBoxRet = 0x4612E8;
static void __declspec(naked) BarBoxesIndexHack() { static void __declspec(naked) BarBoxesIndexHack() {
static const DWORD SetIndexBoxRet = 0x4612E8;
__asm { __asm {
mov eax, ds:[0x4612E2]; // fontnum mov eax, ds:[0x4612E2]; // fontnum
mov ecx, setBoxIndex; // start index mov ecx, setBoxIndex; // start index
@@ -125,9 +125,9 @@ static void __declspec(naked) BarBoxesIndexHack() {
} }
} }
static const DWORD SizeLoopBoxRet = 0x461477;
static const DWORD ExitLoopBoxRet = 0x461498;
static void __declspec(naked) BarBoxesSizeHack() { static void __declspec(naked) BarBoxesSizeHack() {
static const DWORD SizeLoopBoxRet = 0x461477;
static const DWORD ExitLoopBoxRet = 0x461498;
__asm { __asm {
cmp edx, sizeBox; cmp edx, sizeBox;
jz exitLoop; jz exitLoop;

Some files were not shown because too many files have changed in this diff Show More