Compare commits

...
42 Commits
Author SHA1 Message Date
NovaRain de5c12484d Added DataLoadOrderPatch option to use a modified data load order for the engine to find game data (from Crafty's mod)
Updated version number.
2016-10-11 11:58:17 +08:00
NovaRain c880ae93a9 Removed unused code in ScriptExtender.cpp and rename obj_outline_all_items_* functions slightly to prevent using the same names as game engine functions.
Minor edits on main.cpp and Bugs.cpp.
2016-10-07 10:31:46 +08:00
NovaRain 295a5d1437 Replaced NumberPatchLoop with a simple toggleable MultiPatches. Reason: While NumberPatchLoop allows even larger patch numbers, the built-in valid range of patch numbers of 000 ~ 999 is more than enough already. 2016-10-05 16:09:22 +08:00
NovaRain e726ee54ba Tweaked set_bodypart_hit_modifier function to follow the removal of BodyHit_Uncalled from ddraw.ini, e.g. setting modifier for torso (3) will also set for uncalled (8), and vice versa. 2016-10-04 10:23:17 +08:00
NovaRain 712eafc241 Now sfall loads global/hook scripts, shaders, 32-bit talking heads images, and avi movies according to the paths variables in the cfg file, instead of from the fixed "Data\".
Removed GainStatPerkFix from ddraw.ini.
Removed BodyHit_Uncalled from ddraw.ini. Now "uncalled" shares the same modifier with "torso", because separating them would result in some illogical setups.
2016-10-03 14:46:51 +08:00
NovaRain d1bf22ec8d Expanded DisableHorrigan to also skip the forced encounter check, to compatible with old saves that are not started with DisableHorrigan=1.
Changed the description of PipBoyAvailableAtGameStart=2 to be more precise.
Simplified the skipping code in PerkSetup(), because it's redundant to change two bytes that the same effect can be done with changing the conditional jump next to them.
2016-09-29 13:37:58 +08:00
NovaRain 21d496f392 Added a new setting to PipBoyAvailableAtGameStart to skip the vault suit movie check and make the PipBoy always available.
Improved the functionality of PipBoyAvailableAtGameStart (from Crafty's mod)
2016-09-26 16:05:18 +08:00
NovaRain 07948206fb Removed CarryWeightLimit option, because it can be scripted with set_stat_max function. 2016-09-21 09:33:11 +08:00
NovaRain 6a71bf086d Added a partial fix for incorrect positioning after exiting small locations (e.g. Ghost Farm) (from Crafty's mod) 2016-09-19 13:15:57 +08:00
NovaRain ec585529c8 Changed BodypartHitMod# to BodyHit_(part names) in ddraw.ini, to make them easier for users to understand. 2016-08-31 10:27:03 +08:00
NovaRain e6aad27e44 Moved ImportedProcedureFix to Bugs.cpp and added comments to it.
Added more descriptions to options in ddraw.ini, especially DebugMode,  to make things clearer and save the trouble to look up debug patch readme.
2016-08-30 13:11:06 +08:00
NovaRain f0528740a4 Removed the redundant loop in the unlimited ammo exploit fix. 2016-08-22 09:42:01 +08:00
NovaRain bfd8b38547 Merge branch 'develop', preparing for 3.7.3 release. 2016-08-15 14:54:40 +08:00
NovaRain e6086f984e Merge branch 'Vennor-feature/extra_msg'
Feature tested/verified.
2016-08-15 14:38:53 +08:00
NovaRain 2e766cd3c9 Merge branch 'feature/extra_msg' of https://github.com/Vennor/sfall into Vennor-feature/extra_msg
# Conflicts:
#	sfall/Message.cpp
#	sfall/Message.h
2016-08-15 14:38:18 +08:00
NovaRain 48f53388fd Fixed checking the horizontal position on the y-axis instead of x when setting coordinates on the world map.
Added more item flag defines in define_extra.h.
2016-08-15 10:32:53 +08:00
NovaRain 6199f95c38 Fixed incorrect death animations being used when killing critters with kill_critter_type function, e.g. ghouls die standing. (from Crafty) 2016-08-04 12:19:00 +08:00
NovaRain a6d84bd470 Fixed incorrect savegame path detection when reading/writing sfallgv.sav and sfallfs.sav under certain circumstances. (from Crafty) 2016-08-01 16:45:12 +08:00
NovaRain a11228a5ec Fixed get_screen_width/height functions not returning correct values when using older versions of hi-res patch.
Corrected the parameter for intface_update_ac_ in wield_obj_critter fix.
Update the unlimited ammo exploit fix from Crafty's mod.
Removed unnecessary engine-related defines and constants that were added since 3.7b.
2016-07-28 17:05:40 +08:00
NovaRain 7784e199af Integrated NumbersInDialogue option from Crafy's mod.
Moved NPCLevelFix to Bugs.cpp.
Used "push retn" instead of "mov jmp" for some jumps, to skip using registers (at least in logic).
Changed the displayed version number to the same as the internal version number.
2016-07-26 11:03:56 +08:00
NovaRain 53895a4af2 Added CreditsAtBottom option to display sfall built-in credits at the bottom of credits.txt contents.
Unified log message format in main.cpp and bugs.cpp.
2016-07-18 16:54:13 +08:00
phobos2077 354b938d60 Added optional function to show additional sfall credits at the bottom of CREDITS.TXT contents 2016-07-17 23:11:43 +07:00
NovaRain 643d8d3886 Added fix for destroy_p_proc not being called if the critter is killed by explosives when you leave the map.
Integrated Crafty's explosives crash fix.
Updated the link of NMA forum post in the comment.
2016-07-13 15:59:14 +08:00
NovaRain 924c35d011 Improved the unlimited ammo exploit fix to prevent crashes during map transition in RP new areas. (from Crafty)
Updated set_new_results_hack with Crafty's newer code base.
2016-07-12 09:47:26 +08:00
NovaRain 86163bf94c Changed the script procs defines in ScriptExtender.h to their real procedure names in SSL. 2016-07-06 17:15:05 +08:00
NovaRain 21b2d34432 Added some new engine-related defines and constants. 2016-06-03 09:38:31 +08:00
NovaRain 98508a9c76 Added a bug fix for incorrect initialization of action points at the beginning of each turn (from Crafty's mod)
Removed unused code in Bugs.cpp.
2016-05-27 10:37:12 +08:00
NovaRain f8b232cc09 Changed how SpeedInterfaceCounterAnims=2 works (from Crafty's mod). Now it updates the hp/ac counter instantly no matter what.
Fixed get_screen_width/height functions not returning correct values when using the windowed mode in the hi-res patch.
Added some new engine-related defines and constants.
2016-05-17 12:20:22 +08:00
NovaRain 394b4b9967 Edited the description of ExtraGameMsgFileList a bit. 2016-05-11 15:33:01 +08:00
NovaRain 1bea84eb3c Added ExtraGameMsgFileList setting to ddraw.ini, and updated message_str_game reference in sfall function notes.txt.
Added a couple of new engine-related defines.
Updated version number. (Need to consider changing to semantic versioning for 3.8.)
2016-05-10 17:18:31 +08:00
NovaRain 26159138e0 Removed the duplicated include from HeroAppearance.cpp. 2016-05-10 12:48:17 +08:00
NovaRain 1883009930 Cleaned up some artifacts in codes. 2016-05-10 12:42:34 +08:00
NovaRain f1289c1e7d Merge branch 'feature/extra_msg' of https://github.com/Vennor/sfall into Vennor-feature/extra_msg
# Conflicts:
#	sfall/Message.cpp
#	sfall/Message.h
2016-05-10 12:33:44 +08:00
Vennor c3e4894243 Moved opening brace to the same line as the function prototype. 2016-05-09 19:34:07 +02:00
Vennor 2330dd97bb Refactored op_message_str_game2 function to always return a valid string value. Now an "Error" string will be returned on error instead of an uninitialized char pointer or an integer value. 2016-05-09 19:10:25 +02:00
Vennor 90b718122d Added string header inclusion to Message.cpp. 2016-05-08 20:15:37 +02:00
Vennor 5ca7ed0dc5 - Renamed ClearExtraGameMsgFiles function to ClearReadExtraGameMsgFiles.
- Moved ClearReadExtraGameMsgFiles function to Message.cpp.
- Added map clearing to ClearReadExtraGameMsgFiles.
- Changed formatting.
2016-05-08 20:13:13 +02:00
Vennor 9bd03bfb76 Changed std::unordered_map to std::tr1::unordered_map for compatibility with older compilers. 2016-05-08 20:09:56 +02:00
Vennor 07b7e270b8 - Encapsulated and moved ReadExtraGameMsgFiles function call from NewGame2 to MainMenu. 2016-05-08 16:11:51 +02:00
Vennor f9dbbcdca2 - Tidied up extra game message getter a bit.
- Removed unnecessary function call.
2016-05-08 15:53:05 +02:00
Vennor b8968c5334 - Added extra msg file reading based on names given in ddraw.ini.
- Added fetching strings from extra msg files.
2016-04-02 18:43:52 +02:00
Vennor 4f6b68ca93 - Moved existing msg file reading functions and structs from HeroAppearance.cpp to a dedicated Message.h/.cpp file pair.
- Added extern map to hold read extra msg files.
2016-04-02 18:41:59 +02:00
30 changed files with 904 additions and 562 deletions
+44 -23
View File
@@ -1,5 +1,5 @@
;sfall configuration settings
;v3.7b
;v3.7.4
[Main]
;Change to 1 if you want to use command line args to tell sfall to use another ini file.
@@ -201,9 +201,14 @@ WorldMapSlots=0
;To use a patch file other than patch000.dat, uncomment the next line and add your new file name
;If you want to check for multiple patch files, you can include a %d in the file name (sprintf syntax)
;By default, only the first patch file found will be used.
;If you want to load multiple patch files at once, uncomment the NumberPatchLoop line and set it to the number of files to check for
;If you want to load multiple patch files (up to 1000) at once, uncomment the MultiPatches line and set it to 1
;PatchFile=patch%03d.dat
;NumberPatchLoop=100
;MultiPatches=0
;Set to 1 to enable the modified data load order for the engine to find game data
;Original: patchXXX.dat > critter_patches > critter_dat > f2_res_patches > f2_res_dat > master_patches > master_dat
;Modified: master_patches > critter_patches > patchXXX.dat > critter_dat > f2_res_patches > f2_res_dat > master_dat
DataLoadOrderPatch=0
;To change the default and starting player models, uncomment the next four lines.
;The default models can also be changed ingame via script
@@ -247,6 +252,7 @@ Movie17=credits.mve
;PerksFile=Perks.ini
;Set to 1 if you want the pipboy to be available at the start of the game
;Set to 2 to make the pipboy available by only skipping the vault suit movie check
PipBoyAvailableAtGameStart=0
;Set to 1 to double the number of available kill types
@@ -290,9 +296,6 @@ SingleCore=1
;Set to 1 to override the art_chache_size setting in fallout2.cfg
OverrideArtCacheSize=0
;Set to 1 to fix issues with the GainXXX perks not giving all the bonuses that they should
GainStatPerkFix=1
;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.
;Set to 2 to block all saving in combat
@@ -301,7 +304,7 @@ SaveInCombatFix=1
;Point at an ini file containing elevator data
;ElevatorsFile=Elevators.ini
;Uncomment and set to a comma delimited list of numbers to use a custom xp table.
;Uncomment and set a comma delimited list of numbers to use a custom xp table.
;Players level is capped once the highest specified level is reached
;XPTable=50,100,200
@@ -311,15 +314,14 @@ SaveInCombatFix=1
AdditionalWeaponAnims=1
;Uncomment these lines to modify the default modifiers for aimed shots at specific bodyparts
;BodypartHitMod0=-40
;BodypartHitMod1=-30
;BodypartHitMod2=-30
;BodypartHitMod3=0
;BodypartHitMod4=-20
;BodypartHitMod5=-20
;BodypartHitMod6=-60
;BodypartHitMod7=-30
;BodypartHitMod8=0
;BodyHit_Head=-40
;BodyHit_Left_Arm=-30
;BodyHit_Right_Arm=-30
;BodyHit_Torso=0
;BodyHit_Right_Leg=-20
;BodyHit_Left_Leg=-20
;BodyHit_Eyes=-60
;BodyHit_Groin=-30
;Set to 1 to use a CriticalOverrides.ini file to override the default critical table
;Set to 2 to use the default critical with bug fixes (doesn't require an ini)
@@ -395,7 +397,7 @@ UseScrollingQuestsList=1
ExtraSaveSlots=0
;Set to 1 to speed up the hp/ac counter animations
;Set to 2 to update the hp/ac counter instantly when the number is not negative
;Set to 2 to update the hp/ac counters instantly
SpeedInterfaceCounterAnims=0
;These lines allow you to control the karma frm's displayed on the character screen
@@ -420,7 +422,7 @@ BonusHtHDamageFix=1
;Set to 1 to display additional points of damage from Bonus HtH/Ranged Damage perks in the inventory
DisplayBonusDamage=0
;Modify the maximum number of animations allowed to run on a map. (Default is 32)
;Modify the maximum number of animations allowed to run on a map. (Default is 32, and the maximum is 127)
AnimationsAtOnceLimit=120
;Set to 1 to remove the limits that stop the player rolling critical successes/misses in the first few days of game time
@@ -480,7 +482,7 @@ QuickPocketsApCostReduction=2
;Set to 1 to allow objects seeing through other objects with their ShootThru flag set
ObjCanSeeObj_ShootThru_Fix=0
;Set to 1 to use the balanced bullet distribution formula for burst attacks
;Set to 1 to enable the balanced bullet distribution formula for burst attacks
ComputeSprayMod=1
;These options modify the bullet distribution of burst attacks if ComputeSprayMod is 1
@@ -531,7 +533,7 @@ PipboyTimeAnimDelay=50
;Set to 0 to disable
;Set to 1 to control all critters in combat
;Set to 2 to control all party members
;If you want to control only specific critters, uncomment the ControlCombatPIDList line and set it to a comma delimited list of PIDs
;If you want to control only specific critters, uncomment the ControlCombatPIDList line and set a comma delimited list of PIDs
ControlCombat=0
;ControlCombatPIDList=62,89,97,107,160,161
@@ -560,8 +562,15 @@ CarChargingFix=1
;Set to 1 to skip weapon equip/unequip animations when performing various actions
InstantWeaponEquip=0
;To change the carry weight limit, uncomment the next line (Default is 999)
;CarryWeightLimit=999
;To add additional game msg files, uncomment the next line and set a comma delimited list of filenames without .msg extension
;You need to use the message_str_game script function to get messages from the files
;ExtraGameMsgFileList=
;Set to 1 to display numbered dialogue options
NumbersInDialogue=0
;Set to 1 to display sfall built-in credits at the bottom of credits.txt contents instead of at the top
CreditsAtBottom=0
;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
[Debugging]
@@ -571,8 +580,20 @@ InstantWeaponEquip=0
;Set to 1 to enable sfall debugging mode
Enable=0
;Fallout 2 Debug Patch
;Set to 1 to enable debugging output to screen or 2 to create a debug.log file
;While you don't need to create an environment variable, you do still need to set the appropriate lines in fallout2.cfg
;-------
;[debug]
;mode=environment
;output_map_data_info=1
;show_load_info=1
;show_script_messages=1
;show_tile_num=1
;[sound]
;debug=1
;debug_sfxc=1
;-------
DebugMode=0
;Change to 1 to skip the compatibility mode check
@@ -592,7 +613,7 @@ DontDeleteProtos=0
;Set to 1 to give scripts direct access to Fallout's address space, and to make arbitrary calls into Fallout's code
AllowUnsafeScripting=0
;These options control what output is saved in the debug log
;These options control what output is saved in the debug log (sfall-log.txt)
;Prints messages duing sfall initialization
Init=0
+40 -21
View File
@@ -2,16 +2,6 @@
#ifndef DEFINE_EXTRA_H
#define DEFINE_EXTRA_H
#define ATTACK_MODE_NONE 0
#define ATTACK_MODE_PUNCH 1
#define ATTACK_MODE_KICK 2
#define ATTACK_MODE_SWING 3
#define ATTACK_MODE_THRUST 4
#define ATTACK_MODE_THROW 5
#define ATTACK_MODE_SINGLE 6
#define ATTACK_MODE_BURST 7
#define ATTACK_MODE_FLAME 8
#define OBJ_TYPE_ITEM (0)
#define OBJ_TYPE_CRITTER (1)
#define OBJ_TYPE_SCENERY (2)
@@ -20,18 +10,47 @@
#define OBJ_TYPE_MISC (5)
#define OBJ_TYPE_SPATIAL (6)
/* Item Common Flags */
#define HIDDEN_ITEM 134217728 // 0x08000000 - Hidden Item
#define ITEM_ACTION_USE 2048 // 0x00000800 - Use (can be used)
#define ITEM_ACTION_USEON 4096 // 0x00001000 - Use On Smth (can be used on anything)
#define ITEM_ACTION_PICKUP 32768 // 0x00008000 - PickUp
#define WEAPON_BIGGUN 256 // 0x00000100 - Big Gun
#define WEAPON_2HAND 512 // 0x00000200 - 2Hnd (weapon is two-handed)
#define ATKMODE_PRI_NONE 0
#define ATKMODE_PRI_PUNCH 1
#define ATKMODE_PRI_KICK 2
#define ATKMODE_PRI_SWING 3
#define ATKMODE_PRI_THRUST 4
#define ATKMODE_PRI_THROW 5
#define ATKMODE_PRI_SINGLE 6
#define ATKMODE_PRI_BURST 7
#define ATKMODE_PRI_FLAME 8
#define ATKMODE_SEC_NONE 0
#define ATKMODE_SEC_PUNCH 16 // 0x00000010
#define ATKMODE_SEC_KICK 32 // 0x00000020
#define ATKMODE_SEC_SWING 48 // 0x00000030
#define ATKMODE_SEC_THRUST 64 // 0x00000040
#define ATKMODE_SEC_THROW 80 // 0x00000050
#define ATKMODE_SEC_SINGLE 96 // 0x00000060
#define ATKMODE_SEC_BURST 112 // 0x00000070
#define ATKMODE_SEC_FLAME 128 // 0x00000080
/* Critter Flags */
#define CFLG_BARTER 2 //0x00000002 - Barter (can trade with)
#define CFLG_NOSTEAL 32 //0x00000020 - Steal (cannot steal from)
#define CFLG_NODROP 64 //0x00000040 - Drop (doesn't drop items)
#define CFLG_NOLIMBS 128 //0x00000080 - Limbs (cannot lose limbs)
#define CFLG_NOAGES 256 //0x00000100 - Ages (dead body does not disappear)
#define CFLG_NOHEAL 512 //0x00000200 - Heal (damage is not cured with time)
#define CFLG_INVULN 1024 //0x00000400 - Invulnerable (cannot be hurt)
#define CFLG_FLATTN 2048 //0x00000800 - Flatten (leaves no dead body)
#define CFLG_SPECIAL 4096 //0x00001000 - Special (there is a special type of death)
#define CFLG_RANGED 8192 //0x00002000 - Range (melee attack is possible at a distance)
#define CFLG_NOKNOCKDOWN 16384 //0x00004000 - Knock (cannot be knocked down)
#define CFLG_BARTER 2 // 0x00000002 - Barter (can trade with)
#define CFLG_NOSTEAL 32 // 0x00000020 - Steal (cannot steal from)
#define CFLG_NODROP 64 // 0x00000040 - Drop (doesn't drop items)
#define CFLG_NOLIMBS 128 // 0x00000080 - Limbs (cannot lose limbs)
#define CFLG_NOAGES 256 // 0x00000100 - Ages (dead body does not disappear)
#define CFLG_NOHEAL 512 // 0x00000200 - Heal (damage is not cured with time)
#define CFLG_INVULN 1024 // 0x00000400 - Invulnerable (cannot be hurt)
#define CFLG_FLATTN 2048 // 0x00000800 - Flatten (leaves no dead body)
#define CFLG_SPECIAL 4096 // 0x00001000 - Special (there is a special type of death)
#define CFLG_RANGED 8192 // 0x00002000 - Range (melee attack is possible at a distance)
#define CFLG_NOKNOCKDOWN 16384 // 0x00004000 - Knock (cannot be knocked down)
//remove inven obj defines
#define RMOBJ_CONSUME_DRUG 4666772
@@ -277,6 +277,7 @@ Some utility/math functions are available:
> string message_str_game(int fileId, int messageId)
- works exactly the same as message_str, except you get messages from files in "text/english/game" folder
- use GAME_MSG_* defines or mstr_* macros from sfall.h to use specific msg file
- Additional game msg files added by ExtraGameMsgFileList setting will have consecutive fileIds assigned beginning from 0x2000. (e.g. if you set ExtraGameMsgFileList=foo,bar in ddraw.ini, foo.msg will be associated with 0x2000 and bar.msg with 0x2001.)
> int sneak_success
- returns 1 if last sneak attempt (roll against skill) was successful, 0 otherwise
+2 -2
View File
@@ -658,8 +658,8 @@ static void __declspec(naked) DisplayBonusHtHDmg2() {
push eax
call sprintf_
add esp, 4*5
mov eax, 0x472569
jmp eax
push 0x472569
retn
}
}
+210 -76
View File
@@ -3,6 +3,7 @@
#include "Bugs.h"
#include "Define.h"
#include "FalloutEngine.h"
#include "ScriptExtender.h"
DWORD WeightOnBody = 0;
@@ -82,15 +83,15 @@ isCar:
cmp eax, -1
jne skip
notCar:
mov eax, 0x49C38B
jmp eax // "That does nothing."
push 0x49C38B
retn // "That does nothing."
skip:
test eax, eax
jnz end
dec eax
end:
mov esi, 0x49C3C5
jmp esi
push 0x49C3C5
retn
}
}
@@ -126,8 +127,8 @@ skip:
mov eax, dword ptr ds:[_obj_dude]
call queue_find_first_
end:
mov esi, 0x47A6A1
jmp esi
push 0x47A6A1
retn
}
}
@@ -158,30 +159,10 @@ skip:
mov eax, 2 // type = addiction
mov edx, offset remove_jet_addict
call queue_clear_type_
mov eax, 0x479FD1
jmp eax
}
}
/*
static void __declspec(naked) item_wd_process_hook() {
__asm {
cmp esi, PERK_add_jet
je itsJet
push 0x479FD1
retn
itsJet:
pop edx // Destroying the return address
xor edx, edx // edx=init
mov ecx, dword ptr [ebx+0x4] // ecx=drug_pid
push ecx
mov ecx, esi // ecx=perk
mov ebx, 2880 // ebx=time
call insert_withdrawal_
mov eax, 0x47A3FB
jmp eax
}
}
*/
static void __declspec(naked) item_d_load_hack() {
__asm {
@@ -296,26 +277,25 @@ static void __declspec(naked) gdProcessUpdate_hack() {
cmp eax, dword ptr ds:[_optionRect + 0xC] // _optionRect.offy
jge skip
add eax, 2
mov esi, 0x44702D
jmp esi
push 0x44702D
retn
skip:
mov esi, 0x4470DB
jmp esi
push 0x4470DB
retn
}
}
static void __declspec(naked) invenWieldFunc_item_get_type_hook() {
__asm {
pushad
mov edx, esi
xor ebx, ebx
inc ebx
push ebx
mov cl, byte ptr [edi+0x27]
and cl, 0x3
xchg edx, eax // eax=who, edx=item
xchg edx, eax // eax = who, edx = item
call item_remove_mult_
nextWeapon:
xchg ebx, eax
mov eax, esi
test cl, 0x2 // Right hand?
jz leftHand // No
@@ -327,14 +307,16 @@ removeFlag:
test eax, eax
jz noWeapon
and byte ptr [eax+0x27], 0xFC // Unset flag of a weapon in hand
jmp nextWeapon
noWeapon:
or byte ptr [edi+0x27], cl // Set flag of a weapon in hand
xchg esi, eax
mov edx, edi
inc ebx
pop ebx
jz skip
mov eax, esi
mov edx, edi
call item_add_force_
popad
skip:
mov eax, edi
jmp item_get_type_
}
}
@@ -427,8 +409,8 @@ static void __declspec(naked) inven_pickup_hack() {
dec edx
sub edx, eax
lea edx, ds:0[edx*8]
mov eax, 0x470EC9
jmp eax
push 0x470EC9
retn
}
}
@@ -465,8 +447,8 @@ next:
cmp edx, 6
jb next
end:
mov eax, 0x47125C
jmp eax
push 0x47125C
retn
found:
mov ebx, 0x4711DF
add edx, [esp+0x40] // inventory_offset
@@ -545,16 +527,15 @@ end:
static void __declspec(naked) item_d_take_drug_hack1() {
__asm {
mov eax, 0x47A168
jmp eax
push 0x47A168
retn
}
}
// TODO: check if it's still needed
static void __declspec(naked) op_wield_obj_critter_adjust_ac_hook() {
__asm {
call adjust_ac_
xor ecx, ecx
xor eax, eax // not animated
jmp intface_update_ac_
}
}
@@ -611,16 +592,14 @@ static void __declspec(naked) set_new_results_hack() {
__asm {
test ah, 0x1 // DAM_KNOCKED_OUT?
jz end // No
mov dword ptr ds:[_critterClearObj], esi
mov edx, critterClearObjDrugs_
xor eax, eax
inc eax // type = knockout
call queue_clear_type_ // Remove knockout from queue (if there is one)
retn
mov eax, esi
xor edx, edx
inc edx // type = knockout
jmp queue_remove_this_ // Remove knockout from queue (if there is one)
end:
pop eax // Destroying return address
mov eax, 0x424FC6
jmp eax
push 0x424FC6
retn
}
}
@@ -639,13 +618,12 @@ end:
pop esi
pop ecx
pop ebx
retn
retn
}
}
static void __declspec(naked) obj_load_func_hack() {
__asm {
mov edi, 0x488EF9
test byte ptr [eax+0x25], 0x4 // Temp_
jnz end
mov edi, [eax+0x64]
@@ -665,9 +643,11 @@ static void __declspec(naked) obj_load_func_hack() {
clear:
and word ptr [eax+0x44], 0x7FFD // not (DAM_LOSE_TURN or DAM_KNOCKED_DOWN)
skip:
mov edi, 0x488F14
push 0x488F14
retn
end:
jmp edi
push 0x488EF9
retn
}
}
@@ -678,6 +658,62 @@ static void __declspec(naked) partyMemberPrepLoadInstance_hack() {
}
}
static void __declspec(naked) combat_ctd_init_hack() {
__asm {
mov [esi+0x24], eax // ctd.targetTile
mov eax, [ebx+0x54] // pobj.who_hit_me
inc eax
jnz end
mov [ebx+0x54], eax // pobj.who_hit_me
end:
push 0x422F11
retn
}
}
static void __declspec(naked) obj_save_hack() {
__asm {
inc eax
jz end
dec eax
mov edx, [esp+0x1C] // combat_data
mov eax, [eax+0x68] // pobj.who_hit_me.cid
test byte ptr ds:[_combat_state], 1 // in combat?
jz clear // No
cmp dword ptr [edx], 0 // in combat?
jne skip // Yes
clear:
xor eax, eax
dec eax
skip:
mov [edx+0x18], eax // combat_data.who_hit_me
end:
push 0x489422
retn
}
}
static void __declspec(naked) action_explode_hack() {
__asm {
mov edx, destroy_p_proc
mov eax, [esi+0x78] // pobj.sid
call exec_script_proc_
xor edx, edx
dec edx
retn
}
}
static void __declspec(naked) action_explode_hack1() {
__asm {
push esi
mov esi, [esi+0x40] // ctd.target#
call action_explode_hack
pop esi
retn
}
}
static void __declspec(naked) barter_attempt_transaction_hack() {
__asm {
cmp dword ptr [eax+0x64], PID_ACTIVE_GEIGER_COUNTER
@@ -700,12 +736,65 @@ static void __declspec(naked) item_m_turn_off_hook() {
}
}
static void __declspec(naked) combat_hack() {
__asm {
mov eax, [ecx+eax] // eax = source
test eax, eax
jz end
push eax
mov edx, STAT_max_move_points
call stat_level_
mov edx, ds:[_gcsd]
test edx, edx
jz skip
add eax, [edx+0x8] // gcsd.free_move
skip:
pop edx
xchg edx, eax // eax = source, edx = Max action points
mov [eax+0x40], edx // pobj.curr_mp
test byte ptr ds:[_combat_state], 1 // in combat?
jz end // No
mov edx, [eax+0x68] // pobj.cid
cmp edx, -1
je end
push eax
mov eax, ds:[_aiInfoList]
shl edx, 4
mov dword ptr [edx+eax+0xC], 0 // aiInfo.lastMove
pop eax
end:
mov edx, edi // dude_turn
retn
}
}
static void __declspec(naked) wmTeleportToArea_hack() {
__asm {
cmp ebx, ds:[_WorldMapCurrArea]
je end
mov ds:[_WorldMapCurrArea], ebx
sub eax, edx
add eax, ds:[_wmAreaInfoList]
mov edx, [eax+0x30] // wmAreaInfoList.world_posy
mov ds:[_world_ypos], edx
mov edx, [eax+0x2C] // wmAreaInfoList.world_posx
mov ds:[_world_xpos], edx
end:
xor eax, eax
mov ds:[_target_xpos], eax
mov ds:[_target_ypos], eax
mov ds:[_In_WorldMap], eax
push 0x4C5A77
retn
}
}
void BugsInit()
{
//if (GetPrivateProfileIntA("Misc", "SharpshooterFix", 1, ini)) {
dlog("Applying sharpshooter patch.", DL_INIT);
// http://www.nma-fallout.com/showthread.php?178390-FO2-Engine-Tweaks&p=4050162&viewfull=1#post4050162
// http://www.nma-fallout.com/threads/fo2-engine-tweaks-sfall.178390/page-119#post-4050162
// by Slider2k
HookCall(0x4244AB, &SharpShooterFix); // hooks stat_level_() call in detemine_to_hit_func_()
// // removes this line by making unconditional jump:
@@ -719,14 +808,14 @@ void BugsInit()
dlog("Applying fix for Pip-Boy rest exploit.", DL_INIT);
MakeCall(0x4971C7, &pipboy_hack, false);
MakeCall(0x499530, &PipAlarm_hack, false);
dlogr(" Done.", DL_INIT);
dlogr(" Done", DL_INIT);
// Fix for "Too Many Items" bug
//if (GetPrivateProfileIntA("Misc", "TooManyItemsBugFix", 1, ini)) {
dlog("Applying preventive patch for \"Too Many Items\" bug.", DL_INIT);
HookCall(0x4A596A, &scr_write_ScriptNode_hook);
HookCall(0x4A59C1, &scr_write_ScriptNode_hook);
dlogr(" Done.", DL_INIT);
dlogr(" Done", DL_INIT);
//}
// Fix for cells getting consumed even when the car is already fully charged
@@ -736,21 +825,18 @@ void BugsInit()
if (GetPrivateProfileIntA("Misc", "CarChargingFix", 1, ini)) {
dlog("Applying car charging fix.", DL_INIT);
MakeCall(0x49C36D, &protinst_default_use_item_hack, true);
dlogr(" Done.", DL_INIT);
dlogr(" Done", DL_INIT);
}
// makes jet addiction eternal.. why?
//MakeCall(0x47A3A4, &item_wd_process_hook, false);
// Fix for gaining stats from more than two doses of a specific chem after save-load
dlog("Applying fix for save-load unlimited drug use exploit.", DL_INIT);
MakeCall(0x47A243, &item_d_load_hack, false);
dlogr(" Done.", DL_INIT);
dlogr(" Done", DL_INIT);
// Fix crash when leaving the map while waiting for someone to die of a super stimpak overdose
dlog("Applying fix for \"leaving the map while waiting for a super stimpak overdose death\" crash.", DL_INIT);
HookCall(0x4A27E7, &queue_clear_type_mem_free_hook); // hooks mem_free_()
dlogr(" Done.", DL_INIT);
dlogr(" Done", DL_INIT);
// Evil bug! If party member has the same armor type in inventory as currently equipped, then
// on level up he loses Armor Class equal to the one received from this armor.
@@ -759,30 +845,30 @@ void BugsInit()
dlog("Applying fix for armor reducing NPC original stats when removed.", DL_INIT);
HookCall(0x495F3B, &partyMemberCopyLevelInfo_stat_level_hook);
HookCall(0x45419B, &correctFidForRemovedItem_adjust_ac_hook);
dlogr(" Done.", DL_INIT);
dlogr(" Done", DL_INIT);
//}
// Fix of invalid stats when party member gains a level while being on drugs
dlog("Applying fix for addicted party member level up bug.", DL_INIT);
HookCall(0x495D5C, &partyMemberCopyLevelInfo_hook);
dlogr(" Done.", DL_INIT);
dlogr(" Done", DL_INIT);
// Allow 9 options (lines of text) to be displayed correctly in a dialog window
if (GetPrivateProfileIntA("Misc", "DialogOptions9Lines", 1, ini)) {
dlog("Applying 9 dialog options patch.", DL_INIT);
MakeCall(0x44701C, &gdProcessUpdate_hack, true);
dlogr(" Done.", DL_INIT);
dlogr(" Done", DL_INIT);
}
// Fix for "Unlimited Ammo" bug
dlog("Applying fix for Unlimited Ammo bug.", DL_INIT);
// Fix for "Unlimited Ammo" exploit
dlog("Applying fix for Unlimited Ammo exploit.", DL_INIT);
HookCall(0x472957, &invenWieldFunc_item_get_type_hook); // hooks item_get_type_()
dlogr(" Done.", DL_INIT);
dlogr(" Done", DL_INIT);
// Fix for negative values in Skilldex window ("S")
dlog("Applying fix for negative values in Skilldex window.", DL_INIT);
SafeWrite8(0x4AC377, 0x7F); // jg
dlogr(" Done.", DL_INIT);
dlogr(" Done", DL_INIT);
// Fix for not counting in the weight of equipped items on NPC when stealing or bartering
//if (GetPrivateProfileIntA("Misc", "NPCWeightFix", 1, ini)) {
@@ -792,7 +878,7 @@ void BugsInit()
HookCall(0x474CB8, &barter_attempt_transaction_hook);
HookCall(0x4742AD, &move_inventory_hook);
HookCall(0x4771B5, &item_add_mult_hook);
dlogr(" Done.", DL_INIT);
dlogr(" Done", DL_INIT);
//}
// Corrects "Weight of items" text element width to be 64 (and not 80), which matches container element width
@@ -812,6 +898,12 @@ void BugsInit()
dlogr(" Done", DL_INIT);
//}
//if (GetPrivateProfileIntA("Misc", "NPCLevelFix", 1, ini)) {
dlog("Applying NPC level fix.", DL_INIT);
HookCall(0x495BC9, (void*)0x495E51);
dlogr(" Done", DL_INIT);
//}
//if (GetPrivateProfileIntA("Misc", "BlackSkilldexFix", 1, ini)) {
dlog("Applying black skilldex patch.", DL_INIT);
HookCall(0x497D0F, &PipStatus_AddHotLines_hook);
@@ -836,7 +928,7 @@ void BugsInit()
// proper checks for NPC's addiction instead of always using global vars
MakeCall(0x47A644, &item_d_check_addict_hack, true);
MakeCall(0x479FC5, &item_d_take_drug_hack, true);
dlogr(" Done.", DL_INIT);
dlogr(" Done", DL_INIT);
//}
//if (GetPrivateProfileInt("Misc", "ShivPatch", 1, ini)) {
@@ -845,6 +937,17 @@ void BugsInit()
dlogr(" Done", DL_INIT);
//}
//if (GetPrivateProfileInt("Misc", "ImportedProcedureFix", 0, ini)) {
dlog("Applying imported procedure patch.", DL_INIT);
// http://teamx.ru/site_arc/smf/index.php-topic=398.0.htm
SafeWrite16(0x46B35B, 0x1C60); // Fix problems with the temporary stack
SafeWrite32(0x46B35D, 0x90909090);
SafeWrite8(0x46DBF1, 0xEB); // Disable warnings
SafeWrite8(0x46DDC4, 0xEB); // Disable warnings
SafeWrite8(0x4415CC, 0x00); // Prevent crashes when re-exporting
dlogr(" Done", DL_INIT);
//}
//if (GetPrivateProfileIntA("Misc", "WieldObjCritterFix", 1, ini)) {
dlog("Applying wield_obj_critter fix.", DL_INIT);
SafeWrite8(0x456912, 0x1E);
@@ -876,6 +979,15 @@ void BugsInit()
dlogr(" Done", DL_INIT);
//}
dlog("Applying fix for explosives bugs.", DL_INIT);
// Fix crashes when killing critters with explosives
MakeCall(0x422F05, &combat_ctd_init_hack, true);
MakeCall(0x489413, &obj_save_hack, true);
// Fix for destroy_p_proc not being called if the critter is killed by explosives when you leave the map
MakeCall(0x4130C3, &action_explode_hack, false);
MakeCall(0x4130E5, &action_explode_hack1, false);
dlogr(" Done", DL_INIT);
// Fix for unable to sell used geiger counters or stealth boys
if (GetPrivateProfileIntA("Misc", "CanSellUsedGeiger", 1, ini)) {
dlog("Applying fix for unable to sell used geiger counters or stealth boys.", DL_INIT);
@@ -885,4 +997,26 @@ void BugsInit()
HookCall(0x4798B1, &item_m_turn_off_hook);
dlogr(" Done", DL_INIT);
}
// Fix for incorrect initialization of action points at the beginning of each turn
dlog("Applying Action Points initialization fix.", DL_INIT);
BlockCall(0x422E02);
MakeCall(0x422E1B, &combat_hack, false);
dlogr(" Done", DL_INIT);
// Fix for incorrect death animations being used when killing critters with kill_critter_type function
dlog("Applying kill_critter_type fix.", DL_INIT);
SafeWrite16(0x457E22, 0xDB31); // xor ebx, ebx
SafeWrite32(0x457C99, 0x30BE0075); // jnz loc_457C9B; mov esi, 48
dlogr(" Done", DL_INIT);
// Fix for checking the horizontal position on the y-axis instead of x when setting coordinates on the world map
SafeWrite8(0x4C4743, 0xC6); // cmp esi, eax
// Partial fix for incorrect positioning after exiting small locations (e.g. Ghost Farm)
//if (GetPrivateProfileIntA("Misc", "SmallLocExitFix", 1, ini)) {
dlog("Applying fix for incorrect positioning after exiting small locations.", DL_INIT);
MakeCall(0x4C5A41, &wmTeleportToArea_hack, true);
dlogr(" Done", DL_INIT);
//}
}
+52 -23
View File
@@ -22,10 +22,10 @@
#include "FalloutEngine.h"
#include "version.h"
static DWORD InCredits=0;
static DWORD CreditsLine=0;
static DWORD InCredits = 0;
static DWORD CreditsLine = 0;
static const char* ExtraLines[]={
static const char* ExtraLines[] = {
"#SFALL " VERSION_STRING,
"",
"sfall is free software, licensed under the GPL",
@@ -71,42 +71,43 @@ static const char* ExtraLines[]={
"#FALLOUT 2",
""
};
static DWORD ExtraLineCount=sizeof(ExtraLines)/4;
static DWORD ExtraLineCount = sizeof(ExtraLines)/4;
static const char* creditsFile="credits.txt";
static const char* creditsFile = "credits.txt";
static void _stdcall ShowCreditsHook() {
InCredits=1;
CreditsLine=0;
InCredits = 1;
CreditsLine = 0;
__asm {
mov eax, creditsFile;
mov eax, creditsFile;
call credits_;
}
InCredits=0;
InCredits = 0;
}
static DWORD _stdcall CreditsNextLine(char* buf, DWORD* font, DWORD* colour) {
if(!InCredits||CreditsLine>=ExtraLineCount) return 0;
const char* line=ExtraLines[CreditsLine++];
if(strlen(line)) {
if(line[0]=='#') {
if (!InCredits || CreditsLine >= ExtraLineCount) return 0;
const char* line = ExtraLines[CreditsLine++];
if (strlen(line)) {
if (line[0] == '#') {
line++;
*font=*(DWORD*)_name_font;
*colour=*(BYTE*)0x6A7F01;
} else if(line[0]=='@') {
*font = *(DWORD*)_name_font;
*colour = *(BYTE*)0x6A7F01;
} else if (line[0] == '@') {
line++;
*font=*(DWORD*)_title_font;
*colour=*(DWORD*)_title_color;
*font = *(DWORD*)_title_font;
*colour = *(DWORD*)_title_color;
} else {
*font=*(DWORD*)_name_font;
*colour=*(DWORD*)_name_color;
*font = *(DWORD*)_name_font;
*colour = *(DWORD*)_name_color;
}
}
strcpy_s(buf, 256, line);
return 1;
}
static void __declspec(naked) CreditsNextLineHook() {
// Additional lines will be at the top of CREDITS.TXT contents
static void __declspec(naked) CreditsNextLineHook_Top() {
__asm {
pushad;
push ebx;
@@ -115,7 +116,7 @@ static void __declspec(naked) CreditsNextLineHook() {
call CreditsNextLine;
test eax, eax;
popad;
jz fail;
jz fail;
xor eax, eax;
inc eax;
retn;
@@ -124,8 +125,36 @@ fail:
}
}
// Additional lines will be at the bottom of CREDITS.TXT contents
static void __declspec(naked) CreditsNextLineHook_Bottom() {
__asm {
pushad;
call credits_get_next_line_; // call default function
test eax, eax;
popad;
jnz morelines; // if not the end yet, skip custom code
pushad;
push ebx;
push edx;
push eax;
call CreditsNextLine; // otherwise call out function
test eax, eax; // if any extra lines left, return 1 (from function), 0 otherwise
popad;
jnz morelines;
theend:
mov eax, 0x0;
retn;
morelines:
mov eax, 0x1;
retn;
}
}
void CreditsInit() {
HookCall(0x480C49, &ShowCreditsHook);
HookCall(0x43F881, &ShowCreditsHook);
HookCall(0x42CB49, &CreditsNextLineHook);
if (GetPrivateProfileIntA("Misc", "CreditsAtBottom", 0, ini))
HookCall(0x42CB49, &CreditsNextLineHook_Bottom);
else
HookCall(0x42CB49, &CreditsNextLineHook_Top);
}
+15 -15
View File
@@ -84,29 +84,29 @@ static void __declspec(naked) UnknownHook2() {
static void __declspec(naked) GetNumButtonsHook1() {
__asm {
lea esi, Menus;
mov eax, [esi+edi*4];
mov eax, [_btncnt+eax*4];
mov esi, 0x43F064;
jmp esi;
lea esi, Menus;
mov eax, [esi+edi*4];
mov eax, [_btncnt+eax*4];
push 0x43F064;
retn;
}
}
static void __declspec(naked) GetNumButtonsHook2() {
__asm {
lea edx, Menus;
mov eax, [edx+edi*4];
mov eax, [_btncnt+eax*4];
mov edx, 0x43F18B;
jmp edx;
lea edx, Menus;
mov eax, [edx+edi*4];
mov eax, [_btncnt+eax*4];
push 0x43F18B;
retn;
}
}
static void __declspec(naked) GetNumButtonsHook3() {
__asm {
lea eax, Menus;
mov eax, [eax+edi*4];
mov eax, [_btncnt+eax*4];
mov ebx, 0x43F1EB;
jmp ebx;
lea eax, Menus;
mov eax, [eax+edi*4];
mov eax, [_btncnt+eax*4];
push 0x43F1EB;
retn;
}
}
+2
View File
@@ -375,6 +375,7 @@ const DWORD stat_pc_add_experience_ = 0x4AFAA8;
const DWORD stat_pc_get_ = 0x4AF8FC;
const DWORD stat_pc_set_ = 0x4AF910;
const DWORD stat_set_bonus_ = 0x4AF63C;
const DWORD stricmp_ = 0x4DECE6;
const DWORD strncpy_ = 0x4F014F;
const DWORD switch_hand_ = 0x4714E0;
const DWORD talk_to_translucent_trans_buf_to_buf_ = 0x44AC68;
@@ -419,6 +420,7 @@ const DWORD xfread_ = 0x4DF44C;
const DWORD xfseek_ = 0x4DF5D8;
const DWORD xftell_ = 0x4DF690;
const DWORD xfwrite_ = 0x4DF4E8;
const DWORD xremovepath_ = 0x4DFAB4;
const DWORD xrewind_ = 0x4DF6E4;
const DWORD xungetc_ = 0x4DF3F4;
const DWORD xvfprintf_ = 0x4DF1AC;
+14
View File
@@ -26,6 +26,7 @@
#include "FalloutStructs.h"
#define _aiInfoList 0x510948
#define _ambient_light 0x51923C
#define _art 0x510738
#define _art_name 0x56C9E4
@@ -45,6 +46,7 @@
#define _combat_turn_running 0x51093C
#define _combatNumTurns 0x510940
#define _crit_succ_eff 0x510978
#define _critter_db_handle 0x58E94C
#define _critterClearObj 0x518438
#define _crnt_func 0x664508
#define _curr_font_num 0x51E3B0
@@ -67,7 +69,9 @@
#define _free_perk 0x570A29
#define _game_global_vars 0x5186C0
#define _game_user_wants_to_quit 0x5186CC
#define _gcsd 0x51094C
#define _gdBarterMod 0x51873C
#define _gdNumOptions 0x5186D8
#define _gIsSteal 0x51D430
#define _glblmode 0x5709D0
#define _gmouse_current_cursor 0x518C0C
@@ -83,6 +87,7 @@
#define _i_rhand 0x59E968
#define _i_wid 0x59E964
#define _i_worn 0x59E954
#define _In_WorldMap 0x672E1C
#define _info_line 0x5707D0
#define _interfaceWindow 0x519024
#define _intfaceEnabled 0x518F10
@@ -109,7 +114,9 @@
#define _main_window 0x5194F0
#define _map_elevation 0x519578
#define _map_global_vars 0x51956C
#define _master_db_handle 0x58E948
#define _max 0x56FB50
#define _Meet_Frank_Horrigan 0x672E04
#define _mouse_hotx 0x6AC7D0
#define _mouse_hoty 0x6AC7CC
#define _mouse_is_hidden 0x6AC790
@@ -156,6 +163,7 @@
#define _read_callback 0x51DEEC
#define _RedColor 0x6AB4D0
#define _retvals 0x43EA7C
#define _scr_size 0x6AC9F0
#define _skill_data 0x51D118
#define _slot_cursor 0x5193B8
#define _sneak_working 0x56D77C // DWORD var
@@ -172,6 +180,8 @@
#define _target_stack 0x59E81C
#define _target_stack_offset 0x59E7EC
#define _target_str 0x56D518
#define _target_xpos 0x672E20
#define _target_ypos 0x672E24
#define _text_char_width 0x51E3C4
#define _text_height 0x51E3BC
#define _text_max 0x51E3D4
@@ -184,11 +194,13 @@
#define _trait_data 0x51DB84
#define _view_page 0x664520
#define _wd_obj 0x59E98C
#define _wmAreaInfoList 0x51DDF8
#define _wmLastRndTime 0x51DEA0
#define _wmWorldOffsetX 0x51DE2C
#define _wmWorldOffsetY 0x51DE30
#define _world_xpos 0x672E0C
#define _world_ypos 0x672E10
#define _WorldMapCurrArea 0x672E08
#define _YellowColor 0x6AB8BB
// variables
@@ -529,6 +541,7 @@ extern const DWORD stat_pc_add_experience_;
extern const DWORD stat_pc_get_;
extern const DWORD stat_pc_set_;
extern const DWORD stat_set_bonus_;
extern const DWORD stricmp_;
extern const DWORD strncpy_;
extern const DWORD switch_hand_;
extern const DWORD talk_to_translucent_trans_buf_to_buf_;
@@ -573,6 +586,7 @@ extern const DWORD xfread_;
extern const DWORD xfseek_;
extern const DWORD xftell_;
extern const DWORD xfwrite_;
extern const DWORD xremovepath_;
extern const DWORD xrewind_;
extern const DWORD xungetc_;
extern const DWORD xvfprintf_;
+3 -3
View File
@@ -22,7 +22,7 @@
#include "FileSystem.h"
#include "vector9x.cpp"
extern void GetSavePath(char* buf, int type);
extern void GetSavePath(char* buf, char* ftype);
struct fsFile {
char* data;
@@ -440,7 +440,7 @@ void FileSystemSave(HANDLE h) {
static void FileSystemLoad() {
FileSystemReset();
char buf[MAX_PATH];
GetSavePath(buf, 1);
GetSavePath(buf, "fs");
HANDLE h=CreateFileA(buf, GENERIC_READ, 0, 0, OPEN_EXISTING, 0, 0);
if(h!=INVALID_HANDLE_VALUE) {
@@ -454,8 +454,8 @@ static void FileSystemLoad() {
ReadFile(h, file.data, file.length, &read, 0);
if(UsingFileSystem) files.push_back(file);
}
CloseHandle(h);
}
CloseHandle(h);
}
}
static const DWORD LoadHookRetAddr=0x47CCEE;
+8 -6
View File
@@ -86,7 +86,7 @@ static void _stdcall RunSpecificHookScript(sHookScript *hook) {
if (hook->callback != -1)
RunScriptProcByNum(hook->prog.ptr, hook->callback);
else
RunScriptProc(&hook->prog, start_proc);
RunScriptProc(&hook->prog, start);
}
static void _stdcall RunHookScript(DWORD hook) {
if (hooks[hook].size()) {
@@ -1096,17 +1096,19 @@ void _stdcall RegisterHook( DWORD script, DWORD id, DWORD procNum )
hooks[id].push_back(hook);
}
}
#define LoadHookScript(a,b) _LoadHookScript("data\\scripts\\hs_" a ".int", b)
static void _LoadHookScript(const char* path, int id) {
if(id>=numHooks) return;
static void LoadHookScript(const char* name, int id) {
if (id >= numHooks) return;
WIN32_FIND_DATA file;
HANDLE h;
h = FindFirstFileA(path, &file);
char buf[MAX_PATH];
sprintf(buf, "%s\\scripts\\hs_%s.int", *(char**)_patches, name);
h = FindFirstFileA(buf, &file);
if(h != INVALID_HANDLE_VALUE) {
sScriptProgram prog;
dlog("Loading hook script: ", DL_HOOK);
dlogr(path, DL_HOOK);
dlogr(buf, DL_HOOK);
char* fName = file.cFileName;
fName[strlen(fName) - 4] = 0;
LoadScriptProgram(prog, fName);
+9 -9
View File
@@ -129,12 +129,12 @@ static void __declspec(naked) PickpocketHook() {
push esi;
push eax;
call PickpocketHook2;
pop ebx;
pop ecx;
pop edx;
mov [esp+84], eax;
mov eax, 0x4ABC6F;
jmp eax;
pop ebx;
pop ecx;
pop edx;
mov [esp+84], eax;
push 0x4ABC6F;
retn;
}
}
static int _stdcall HitChanceHook2(int base, DWORD critter) {
@@ -150,9 +150,9 @@ static void __declspec(naked) HitChanceHook() {
push edi;
push esi;
call HitChanceHook2;
mov esi, eax;
mov eax, 0x0042479B;
jmp eax;
mov esi, eax;
push 0x42479B;
retn;
}
}
+55 -88
View File
@@ -31,6 +31,7 @@
#include "Knockback.h"
#include "LoadGameHook.h"
#include "Logging.h"
#include "Message.h"
#include "movies.h"
#include "PartyControl.h"
#include "perks.h"
@@ -43,32 +44,12 @@
#define MAX_GLOBAL_SIZE (MaxGlobalVars*12 + 4)
static DWORD InLoop=0;
DWORD GainStatFix=0;
static DWORD SaveInCombatFix;
DWORD InWorldMap() { return (InLoop&WORLDMAP)?1:0; }
DWORD InCombat() { return (InLoop&COMBAT)?1:0; }
DWORD GetCurrentLoops() { return InLoop; }
static void ModifyGainXXXPerks() {
SafeWrite8(0x004AF11F, 0xeb); //Strength
SafeWrite8(0x004AF181, 0xeb); //Perception
SafeWrite8(0x004AF19D, 0xeb); //Endurance
SafeWrite8(0x004AF1BD, 0xeb); //Charisma
SafeWrite8(0x004AF214, 0xeb); //Intelligance
SafeWrite8(0x004AF230, 0xeb); //Agility
SafeWrite8(0x004AF24B, 0xeb); //Luck
}
static void RestoreGainXXXPerks() {
SafeWrite8(0x004AF11F, 0x74); //Strength
SafeWrite8(0x004AF181, 0x74); //Perception
SafeWrite8(0x004AF19D, 0x74); //Endurance
SafeWrite8(0x004AF1BD, 0x74); //Charisma
SafeWrite8(0x004AF214, 0x74); //Intelligance
SafeWrite8(0x004AF230, 0x74); //Agility
SafeWrite8(0x004AF24B, 0x74); //Luck
}
static void _stdcall ResetState(DWORD onLoad) {
if(!onLoad) FileSystemReset();
ClearGlobalScripts();
@@ -79,8 +60,6 @@ static void _stdcall ResetState(DWORD onLoad) {
Knockback_OnGameLoad();
Skills_OnGameLoad();
InLoop=0;
GainStatFix=0;
RestoreGainXXXPerks();
PerksReset();
InventoryReset();
RegAnimCombatCheck(1);
@@ -88,50 +67,25 @@ static void _stdcall ResetState(DWORD onLoad) {
PartyControlReset();
}
void GetSavePath(char* buf, int type) {
int saveid = *(int*)_slot_cursor + 1 +LSPageOffset;//add SuperSave Page offset
char buf2[6];
//Fallout saving is independent of working directory
struct sPath {
char* path;
int a;
int b;
sPath* next;
};
sPath* spath=*(sPath**)_paths;
while(spath->a&&spath->next) spath=spath->next;
//strcpy_s(buf, MAX_PATH, **(char***)_paths);
strcpy_s(buf, MAX_PATH, spath->path);
strcat_s(buf, MAX_PATH, "\\savegame\\slot");
_itoa_s(saveid, buf2, 10);
if(strlen(buf2)==1) strcat_s(buf, MAX_PATH, "0");
strcat_s(buf, MAX_PATH, buf2);
switch(type) {
case 0:
strcat_s(buf, MAX_PATH, "\\sfallgv.sav");
break;
case 1:
strcat_s(buf, MAX_PATH, "\\sfallfs.sav");
break;
}
void GetSavePath(char* buf, char* ftype) {
sprintf(buf, "%s\\savegame\\slot%.2d\\sfall%s.sav", *(char**)_patches, *(DWORD*)_slot_cursor + 1 + LSPageOffset, ftype); //add SuperSave Page offset
}
static char SaveSfallDataFailMsg[128];
static void _stdcall SaveGame2() {
char buf[MAX_PATH];
GetSavePath(buf, 0);
GetSavePath(buf, "gv");
dlog_f("Saving game: %s\r\n", DL_MAIN, buf);
DWORD unused;
DWORD unused2=0;
HANDLE h=CreateFileA(buf, GENERIC_WRITE, 0, 0, CREATE_ALWAYS, 0, 0);
if(h!=INVALID_HANDLE_VALUE) {
DWORD size, unused = 0;
HANDLE h = CreateFileA(buf, GENERIC_WRITE, 0, 0, CREATE_ALWAYS, 0, 0);
if (h != INVALID_HANDLE_VALUE) {
SaveGlobals(h);
WriteFile(h, &unused2, 4, &unused, 0);
WriteFile(h, &GainStatFix, 4, &unused, 0);
WriteFile(h, &unused, 4, &size, 0);
unused++;
WriteFile(h, &unused, 4, &size, 0);
PerksSave(h);
SaveArrays(h);
CloseHandle(h);
@@ -140,9 +94,9 @@ static void _stdcall SaveGame2() {
DisplayConsoleMessage(SaveSfallDataFailMsg);
PlaySfx("IISXXXX1");
}
GetSavePath(buf, 1);
h=CreateFileA(buf, GENERIC_WRITE, 0, 0, CREATE_ALWAYS, 0, 0);
if(h!=INVALID_HANDLE_VALUE) {
GetSavePath(buf, "fs");
h = CreateFileA(buf, GENERIC_WRITE, 0, 0, CREATE_ALWAYS, 0, 0);
if (h != INVALID_HANDLE_VALUE) {
FileSystemSave(h);
}
CloseHandle(h);
@@ -210,32 +164,25 @@ static void _stdcall LoadGame2_Before() {
static void _stdcall LoadGame2_After() {
char buf[MAX_PATH];
GetSavePath(buf, 0);
GetSavePath(buf, "gv");
dlog_f("Loading save game: %s\r\n", DL_MAIN, buf);
ClearGlobals();
HANDLE h=CreateFileA(buf, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0);
if(h!=INVALID_HANDLE_VALUE) {
DWORD size=0;
DWORD unused;
HANDLE h = CreateFileA(buf, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0);
if (h != INVALID_HANDLE_VALUE) {
DWORD size, unused[2];
LoadGlobals(h);
ReadFile(h, (&unused), 4, &size, 0);
ReadFile(h, &GainStatFix, 4, &size, 0);
if(!size) GainStatFix = 0;
else {
ReadFile(h, &unused, 8, &size, 0);
if (size == 8) {
PerksLoad(h);
LoadArrays(h);
}
CloseHandle(h);
} else {
GainStatFix = 0;
dlogr("Cannot read sfallgv.sav - assuming non-sfall save.", DL_MAIN);
}
if(GainStatFix) ModifyGainXXXPerks();
else RestoreGainXXXPerks();
LoadGlobalScripts();
CritLoad();
LoadHeroAppearance();
@@ -276,6 +223,7 @@ end:
retn;
}
}
static void NewGame2() {
ResetState(0);
@@ -283,39 +231,44 @@ static void NewGame2() {
SetNewCharAppearanceGlobals();
if(GetPrivateProfileInt("Misc", "GainStatPerkFix", 1, ini)) {
ModifyGainXXXPerks();
GainStatFix=1;
} else {
RestoreGainXXXPerks();
GainStatFix=0;
}
if(GetPrivateProfileInt("Misc", "PipBoyAvailableAtGameStart", 0, ini)) {
SafeWrite8(0x00596C7B, 1);
}
if(GetPrivateProfileInt("Misc", "DisableHorrigan", 0, ini)) {
*(DWORD*)0x00672E04=1;
/*if (GetPrivateProfileInt("Misc", "PipBoyAvailableAtGameStart", 0, ini)) {
SafeWrite8(0x596C7B, 1);
}
if (GetPrivateProfileInt("Misc", "DisableHorrigan", 0, ini)) {
*(DWORD*)0x672E04 = 1;
}*/
LoadGlobalScripts();
CritLoad();
}
static bool DisableHorrigan = false;
static void __declspec(naked) NewGame() {
__asm {
pushad;
call NewGame2;
mov al, DisableHorrigan;
mov byte ptr ds:[_Meet_Frank_Horrigan], al;
popad;
call main_game_loop_;
retn;
}
}
static void ReadExtraGameMsgFilesIfNeeded() {
if (gExtraGameMsgLists.empty())
ReadExtraGameMsgFiles();
}
static bool PipBoyAvailableAtGameStart = false;
static void __declspec(naked) MainMenu() {
__asm {
pushad;
push 0;
call ResetState;
mov al, PipBoyAvailableAtGameStart;
mov byte ptr ds:[_gmovie_played_list + 0x3], al;
call ReadExtraGameMsgFilesIfNeeded;
call LoadHeroAppearance;
popad;
call main_menu_loop_;
@@ -456,13 +409,27 @@ static void __declspec(naked) AutomapHook() {
}
void LoadGameHookInit() {
SaveInCombatFix=GetPrivateProfileInt("Misc", "SaveInCombatFix", 1, ini);
if(SaveInCombatFix>2) SaveInCombatFix=0;
if(SaveInCombatFix) {
SaveInCombatFix = GetPrivateProfileInt("Misc", "SaveInCombatFix", 1, ini);
if (SaveInCombatFix > 2) SaveInCombatFix = 0;
if (SaveInCombatFix) {
GetPrivateProfileString("sfall", "SaveInCombat", "Cannot save at this time", SaveFailMsg, 128, translationIni);
}
GetPrivateProfileString("sfall", "SaveSfallDataFail", "ERROR saving extended savegame information! Check if other programs interfere with savegame files/folders and try again!", SaveSfallDataFailMsg, 128, translationIni);
switch (GetPrivateProfileInt("Misc", "PipBoyAvailableAtGameStart", 0, ini)) {
case 1:
PipBoyAvailableAtGameStart = true;
break;
case 2:
SafeWrite8(0x497011, 0xEB); // skip the vault suit movie check
break;
}
if (GetPrivateProfileInt("Misc", "DisableHorrigan", 0, ini)) {
DisableHorrigan = true;
SafeWrite8(0x4C06D8, 0xEB); // skip the Horrigan encounter check
}
HookCall(0x480AB3, NewGame);
HookCall(0x47C72C, LoadSlot);
+51
View File
@@ -16,11 +16,14 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <string>
#include "main.h"
#include "FalloutEngine.h"
#include "Message.h"
std::tr1::unordered_map<int, MSGList*> gExtraGameMsgLists;
int LoadMsgList(MSGList *MsgList, char *MsgFilePath) {
int retVal;
__asm {
@@ -95,3 +98,51 @@ char* GetMsg(MSGList *MsgList, DWORD msgRef, int msgNum) {
}
return NULL;
}
void ReadExtraGameMsgFiles() {
int read;
std::string names;
names.resize(256);
while ((read = GetPrivateProfileStringA("Misc", "ExtraGameMsgFileList", "",
(LPSTR)names.data(), names.size(), ".\\ddraw.ini")) == names.size() - 1)
names.resize(names.size() + 256);
if (names.empty())
return;
names.resize(names.find_first_of('\0'));
names.append(",");
int begin = 0;
int end;
int length;
while ((end = names.find_first_of(',', begin)) != std::string::npos) {
length = end - begin;
if (length > 0) {
std::string path = "game\\" + names.substr(begin, length) + ".msg";
MSGList* list = new MSGList;
if (LoadMsgList(list, (char*)path.data()) == 1)
gExtraGameMsgLists.insert(std::make_pair(0x2000 + gExtraGameMsgLists.size(), list));
else
delete list;
}
begin = end + 1;
}
}
void ClearReadExtraGameMsgFiles() {
std::tr1::unordered_map<int, MSGList*>::iterator it;
for (it = gExtraGameMsgLists.begin(); it != gExtraGameMsgLists.end(); ++it) {
DestroyMsgList(it->second);
delete it->second;
}
gExtraGameMsgLists.clear();
}
+7
View File
@@ -18,6 +18,9 @@
#pragma once
#include <unordered_map>
#include "main.h"
//for holding a message
typedef struct MSGNode {
DWORD ref;
@@ -44,8 +47,12 @@ typedef struct MSGList {
}
} MSGList;
extern std::tr1::unordered_map<int, MSGList*> gExtraGameMsgLists;
int LoadMsgList(MSGList *MsgList, char *MsgFilePath);
int DestroyMsgList(MSGList *MsgList);
//bool GetMsg(MSGList *MsgList, MSGNode *MsgNode, DWORD msgRef);
MSGNode *GetMsgNode(MSGList *MsgList, DWORD msgRef);
char* GetMsg(MSGList *MsgList, DWORD msgRef, int msgNum);
void ReadExtraGameMsgFiles();
void ClearReadExtraGameMsgFiles();
+57 -48
View File
@@ -78,7 +78,6 @@ vector<FakePerk> fakeTraits;
vector<FakePerk> fakePerks;
vector<FakePerk> fakeSelectablePerks;
extern DWORD GainStatFix;
static DWORD RemoveTraitID;
static DWORD RemovePerkID;
static DWORD RemoveSelectableID;
@@ -91,6 +90,16 @@ static char PerkBoxTitle[64];
static DWORD PerkFreqOverride;
static const DWORD GainStatPerks[7][2] = {
{0x4AF122, 0xC9}, // Strength // mov ecx, ecx
{0x4AF184, 0xC9}, // Perception
{0x4AF19F, 0x90}, // Endurance // nop
{0x4AF1C0, 0xC9}, // Charisma
{0x4AF217, 0xC9}, // Intelligance
{0x4AF232, 0x90}, // Agility
{0x4AF24D, 0x90}, // Luck
};
void _stdcall SetPerkFreq(int i) {
PerkFreqOverride=i;
}
@@ -342,36 +351,36 @@ static void __declspec(naked) PlayerHasPerkHook() {
__asm {
push ecx;
call HandleFakeTraits;
mov ecx, eax;
xor ebx, ebx;
mov ecx, eax;
xor ebx, ebx;
oloop:
mov eax, ds:[_obj_dude];
mov edx, ebx;
mov eax, ds:[_obj_dude];
mov edx, ebx;
call perk_level_;
test eax, eax;
jnz win;
inc ebx;
cmp ebx, PERK_count;
jl oloop;
jnz win;
inc ebx;
cmp ebx, PERK_count;
jl oloop;
call HaveFakePerks;
test eax, eax;
jnz win;
mov ebx, 0x00434446;
jmp ebx;
jnz win;
push 0x434446;
retn;
win:
mov ebx, 0x0043438A;
jmp ebx;
push 0x43438A;
retn;
}
}
static void __declspec(naked) PlayerHasTraitHook() {
__asm {
call HaveFakeTraits;
test eax, eax;
jz end;
mov eax, 0x0043425B;
jmp eax;
jz end;
push 0x43425B;
retn;
end:
jmp PlayerHasPerkHook;
jmp PlayerHasPerkHook;
}
}
@@ -430,14 +439,14 @@ end:
static void __declspec(naked) EndPerkLoopHook() {
__asm {
call HaveFakePerks;
add eax, PERK_count;
cmp ebx, eax;
jl end;
mov eax, 0x00434446;
jmp eax;
add eax, PERK_count;
cmp ebx, eax;
jl end;
push 0x434446;
retn;
end:
mov eax, 0x004343A5;
jmp eax;
push 0x4343A5;
retn;
}
}
@@ -567,10 +576,7 @@ static void __declspec(naked) AddPerkHook() {
end:
push edx;
call perk_add_;
mov edx, GainStatFix;
test edx, edx;
pop edx;
jz end2;
test eax, eax;
jnz end2;
cmp edx, 84;
@@ -585,25 +591,25 @@ end2:
static void __declspec(naked) HeaveHoHook() {
__asm {
xor edx, edx;
mov eax, ecx;
xor edx, edx;
mov eax, ecx;
call stat_level_;
lea ebx, [0+eax*4];
sub ebx, eax;
cmp ebx, esi;
jle lower;
mov ebx, esi;
lea ebx, [0+eax*4];
sub ebx, eax;
cmp ebx, esi;
jle lower;
mov ebx, esi;
lower:
mov eax, ecx;
mov edx, PERK_heave_ho;
mov eax, ecx;
mov edx, PERK_heave_ho;
call perk_level_;
lea ecx, [0+eax*8];
sub ecx, eax;
sub ecx, eax;
mov eax, ecx;
add eax, ebx;
mov edi, 0x478AFC;
jmp edi;
lea ecx, [0+eax*8];
sub ecx, eax;
sub ecx, eax;
mov eax, ecx;
add eax, ebx;
push 0x478AFC;
retn;
}
}
void _stdcall ApplyHeaveHoFix() {
@@ -723,8 +729,7 @@ static void PerkSetup() {
MakeCall(0x4AFB2F, LevelUpHook, false);//replaces 'mov edx, ds:[PlayerLevel]
SafeWrite8(0x4AFB34, 0x90);
SafeWrite8(0x43C2E9, 0xeb); //jmp 0x2e
SafeWrite8(0x43C2EA, 0x2e); //replaces the block of code which checks if the player has gained a perk (now handled in level up code)
SafeWrite8(0x43C2EC, 0xEB); //skip the block of code which checks if the player has gained a perk (now handled in level up code)
SafeWrite8(0x43C362, 0xe8); //call sub_43401C, dec byte ptr ds:[0x00570A29]
SafeWrite32(0x43C363, 0x0043410C - 0x0043C367); //replaces call sub_43401C, mov byte ptr ds:[0x00570A29], 0
@@ -983,14 +988,18 @@ void _stdcall SetPerkDesc(int id, char* value) {
strcpy_s(&Desc[id*1024], 1024, value);
Perks[id].Desc=&Desc[1024*id];
}
void PerksInit() {
for (int i = STAT_st; i <= STAT_lu; i++) SafeWrite8(GainStatPerks[i][0], (BYTE)GainStatPerks[i][1]);
HookCall(0x442729, &PerkInitWrapper);
if(GetPrivateProfileString("Misc", "PerksFile", "", &perksFile[2], 257, ini)) {
if (GetPrivateProfileString("Misc", "PerksFile", "", &perksFile[2], 257, ini)) {
perksFile[0]='.';
perksFile[1]='\\';
HookCall(0x44272E, &TraitInitWrapper);
} else perksFile[0]=0;
} else perksFile[0] = 0;
}
void PerksReset() {
fakeTraits.clear();
fakePerks.clear();
+23 -34
View File
@@ -716,9 +716,9 @@ static void __declspec(naked) AfterCombatAttackHook() {
pushad;
call AfterAttackCleanup;
popad;
mov eax, 1;
mov edx, 0x4230DA;
jmp edx;
mov eax, 1;
push 0x4230DA;
retn;
}
}
static void __declspec(naked) ExecMapScriptsHook() {
@@ -729,8 +729,8 @@ static void __declspec(naked) ExecMapScriptsHook() {
push eax; // int procId
call HandleMapUpdateForScripts;
popad;
mov ebx, 0x4A67F9; // jump back
jmp ebx;
push 0x4A67F9; // jump back
retn;
}
}
static DWORD __stdcall GetGlobalExportedVarPtr(const char* name) {
@@ -823,7 +823,7 @@ static void __declspec(naked) FreeProgramHook() {
}
}
static void __declspec(naked) obj_outline_all_items_on_() {
static void __declspec(naked) obj_outline_all_items_on() {
__asm {
pushad
mov eax, dword ptr ds:[_map_elevation]
@@ -861,7 +861,7 @@ end:
}
}
static void __declspec(naked) obj_outline_all_items_off_() {
static void __declspec(naked) obj_outline_all_items_off() {
__asm {
pushad
mov eax, dword ptr ds:[_map_elevation]
@@ -890,19 +890,6 @@ end:
}
}
/*static void __declspec(naked) gmouse_bk_process_hook() { // NR: for changing mouseover highlight color. do we really need such fancy stuff?
__asm {
test eax, eax
jz end
test byte ptr [eax+0x25], 0x10 // NoHighlight_
jnz end
mov dword ptr [eax+0x74], 0
end:
mov edx, 0x40
jmp obj_outline_object_
}
}*/
static void __declspec(naked) obj_remove_outline_hook() {
__asm {
call obj_remove_outline_
@@ -911,7 +898,7 @@ static void __declspec(naked) obj_remove_outline_hook() {
cmp highlightingToggled, 1
jne end
mov ds:[_outlined_object], eax
call obj_outline_all_items_on_
call obj_outline_all_items_on
end:
retn
}
@@ -1325,7 +1312,9 @@ void LoadGlobalScripts() {
HookScriptInit();
dlogr("Loading global scripts", DL_SCRIPT);
WIN32_FIND_DATA file;
HANDLE h=FindFirstFileA("data\\scripts\\gl*.int", &file);
char buf[MAX_PATH];
sprintf(buf, "%s\\scripts\\gl*.int", *(char**)_patches);
HANDLE h = FindFirstFileA(buf, &file);
if (h != INVALID_HANDLE_VALUE) {
char* fName = file.cFileName;
// TODO: refactor script programs
@@ -1385,15 +1374,15 @@ void ClearGlobalScripts() {
//Stat ranges
StatsReset();
//Bodypart hit chances
*((DWORD*)0x510954)=GetPrivateProfileIntA("Misc", "BodypartHitMod0", 0xFFFFFFD8, ini);
*((DWORD*)0x510958)=GetPrivateProfileIntA("Misc", "BodypartHitMod1", 0xFFFFFFE2, ini);
*((DWORD*)0x51095C)=GetPrivateProfileIntA("Misc", "BodypartHitMod2", 0xFFFFFFE2, ini);
*((DWORD*)0x510960)=GetPrivateProfileIntA("Misc", "BodypartHitMod3", 0x00000000, ini);
*((DWORD*)0x510964)=GetPrivateProfileIntA("Misc", "BodypartHitMod4", 0xFFFFFFEC, ini);
*((DWORD*)0x510968)=GetPrivateProfileIntA("Misc", "BodypartHitMod5", 0xFFFFFFEC, ini);
*((DWORD*)0x51096C)=GetPrivateProfileIntA("Misc", "BodypartHitMod6", 0xFFFFFFC4, ini);
*((DWORD*)0x510970)=GetPrivateProfileIntA("Misc", "BodypartHitMod7", 0xFFFFFFE2, ini);
*((DWORD*)0x510974)=GetPrivateProfileIntA("Misc", "BodypartHitMod8", 0x00000000, ini);
*((DWORD*)0x510954) = GetPrivateProfileIntA("Misc", "BodyHit_Head", 0xFFFFFFD8, ini);
*((DWORD*)0x510958) = GetPrivateProfileIntA("Misc", "BodyHit_Left_Arm", 0xFFFFFFE2, ini);
*((DWORD*)0x51095C) = GetPrivateProfileIntA("Misc", "BodyHit_Right_Arm", 0xFFFFFFE2, ini);
*((DWORD*)0x510960) = GetPrivateProfileIntA("Misc", "BodyHit_Torso", 0x00000000, ini);
*((DWORD*)0x510964) = GetPrivateProfileIntA("Misc", "BodyHit_Right_Leg", 0xFFFFFFEC, ini);
*((DWORD*)0x510968) = GetPrivateProfileIntA("Misc", "BodyHit_Left_Leg", 0xFFFFFFEC, ini);
*((DWORD*)0x51096C) = GetPrivateProfileIntA("Misc", "BodyHit_Eyes", 0xFFFFFFC4, ini);
*((DWORD*)0x510970) = GetPrivateProfileIntA("Misc", "BodyHit_Groin", 0xFFFFFFE2, ini);
*((DWORD*)0x510974) = GetPrivateProfileIntA("Misc", "BodyHit_Torso", 0x00000000, ini);
//skillpoints per level mod
SafeWrite8(0x43C27a, 5);
}
@@ -1422,7 +1411,7 @@ void RunScriptProc(sScriptProgram* prog, DWORD procId) {
}
static void RunScript(sGlobalScript* script) {
script->count=0;
RunScriptProc(&script->prog, start_proc); // run "start"
RunScriptProc(&script->prog, start); // run "start"
}
/**
@@ -1474,11 +1463,11 @@ static void RunGlobalScripts1() {
DisplayConsoleMessage(HighlightFail1);
}
} else highlightingToggled = 1;
if (highlightingToggled) obj_outline_all_items_on_();
if (highlightingToggled) obj_outline_all_items_on();
else highlightingToggled = 2;
}
} else if(highlightingToggled) {
if (highlightingToggled == 1) obj_outline_all_items_off_();
if (highlightingToggled == 1) obj_outline_all_items_off();
highlightingToggled=0;
}
}
+9 -8
View File
@@ -30,7 +30,7 @@ struct sGlobalVar
int val;
};
#define SCRIPT_PROC_MAX (27)
#define SCRIPT_PROC_MAX (27)
typedef struct
{
DWORD ptr;
@@ -86,12 +86,13 @@ static char reg_anim_combat_check = 1;
extern DWORD isGlobalScriptLoading;
// types for script variables
#define VAR_TYPE_INT (0xC001)
#define VAR_TYPE_FLOAT (0xA001)
#define VAR_TYPE_STR (0x9801)
#define VAR_TYPE_STR2 (0x9001)
#define VAR_TYPE_INT (0xC001)
#define VAR_TYPE_FLOAT (0xA001)
#define VAR_TYPE_STR (0x9801)
#define VAR_TYPE_STR2 (0x9001)
// script procs
#define start_proc (1)
#define map_enter_p_proc (15)
#define map_update_proc (23)
#define start (1)
#define map_enter_p_proc (15)
#define destroy_p_proc (18)
#define map_update_p_proc (23)
+29 -26
View File
@@ -168,38 +168,41 @@ static void __declspec(naked) get_window_under_mouse() {
retn;
}
}
//Return screen width
static void __declspec(naked) get_screen_width() {
__asm {
push ecx;
push edx;
mov ecx, eax;
mov edx, ds:[0x4CAD6B];
call interpretPushLong_;
mov eax, ecx;
mov edx, 0xc001;
call interpretPushShort_
pop edx;
pop ecx;
retn;
}
__asm {
push edx
push eax
mov edx, ds:[_scr_size+8] // _scr_size.offx
sub edx, ds:[_scr_size] // _scr_size.x
inc edx
call interpretPushLong_
pop eax
mov edx, 0xc001
call interpretPushShort_
pop edx
retn
}
}
//Return screen height
static void __declspec(naked) get_screen_height() {
__asm {
push ecx;
push edx;
mov ecx, eax;
mov edx, ds:[0x4CAD66];
call interpretPushLong_;
mov eax, ecx;
mov edx, 0xc001;
call interpretPushShort_
pop edx;
pop ecx;
retn;
}
__asm {
push edx
push eax
mov edx, ds:[_scr_size+12] // _scr_size.offy
sub edx, ds:[_scr_size+4] // _scr_size.y
inc edx
call interpretPushLong_
pop eax
mov edx, 0xc001
call interpretPushShort_
pop edx
retn
}
}
//Stop game, the same effect as open charsscreen or inventory
static void __declspec(naked) stop_game() {
__asm {
+62 -53
View File
@@ -570,8 +570,8 @@ static void __declspec(naked) IncNPCLevel3() {
push eax;
call IncNPCLevel4;
popad;
mov eax, 0x00495BF9;
jmp eax;
push 0x495BF9;
retn;
}
}
static void _stdcall IncNPCLevel2(char* npc) {
@@ -872,68 +872,77 @@ end:
}
}
static void __declspec(naked) GetBodypartHitModifier() {
__asm {
push ecx;
push edx;
mov ecx, eax;
call interpretPopShort_;
mov edx, eax;
mov eax, ecx;
call interpretPopLong_;
cmp dx, 0xC001;
jnz fail;
cmp eax, 9;
jg fail;
test eax, eax;
jl fail;
mov edx, ds:[_hit_location_penalty+eax*4];
jmp end;
push ecx
push edx
mov ecx, eax
call interpretPopShort_
mov edx, eax
mov eax, ecx
call interpretPopLong_
cmp dx, VAR_TYPE_INT
jnz fail
cmp eax, 8 // Body_Uncalled?
jg fail
test eax, eax
jl fail
mov edx, ds:[_hit_location_penalty+eax*4]
jmp end
fail:
xor edx, edx;
xor edx, edx
end:
mov eax, ecx;
call interpretPushLong_;
mov eax, ecx;
mov edx, 0xc001;
call interpretPushShort_;
pop edx;
pop ecx;
retn;
mov eax, ecx
call interpretPushLong_
mov eax, ecx
mov edx, VAR_TYPE_INT
call interpretPushShort_
pop edx
pop ecx
retn
}
}
static void __declspec(naked) SetBodypartHitModifier() {
__asm {
push ebx;
push ecx;
push edx;
mov ecx, eax;
call interpretPopShort_;
mov edx, eax;
mov eax, ecx;
call interpretPopLong_;
mov ebx, eax;
mov eax, ecx;
call interpretPopShort_;
xchg eax, ecx;
call interpretPopLong_;
cmp dx, 0xC001;
jnz end;
cmp cx, 0xC001;
jnz end;
cmp eax, 9;
jg end;
test eax, eax;
jl end;
mov ds:[_hit_location_penalty+eax*4], ebx;
push ebx
push ecx
push edx
mov ecx, eax
call interpretPopShort_
mov edx, eax
mov eax, ecx
call interpretPopLong_
mov ebx, eax
mov eax, ecx
call interpretPopShort_
xchg eax, ecx
call interpretPopLong_
cmp dx, VAR_TYPE_INT
jnz end
cmp cx, VAR_TYPE_INT
jnz end
cmp eax, 8 // Body_Uncalled?
jg end
cmp eax, 3 // Body_Torso?
jne skip // No
add eax, 5
skip:
test eax, eax
jl end
mov ds:[_hit_location_penalty+eax*4], ebx
cmp eax, 8 // Body_Uncalled?
jne end // No
sub eax, 5 // Body_Torso
jmp skip
end:
pop edx;
pop ecx;
pop ebx;
retn;
pop edx
pop ecx
pop ebx
retn
}
}
static void __declspec(naked) funcSetCriticalTable() {
__asm {
pushad;

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