mirror of
https://github.com/sfall-team/sfall.git
synced 2026-07-27 16:52:34 -07:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
de5c12484d | ||
|
|
c880ae93a9 | ||
|
|
295a5d1437 | ||
|
|
e726ee54ba | ||
|
|
712eafc241 | ||
|
|
d1bf22ec8d | ||
|
|
21d496f392 | ||
|
|
07948206fb | ||
|
|
6a71bf086d | ||
|
|
ec585529c8 | ||
|
|
e6aad27e44 | ||
|
|
f0528740a4 | ||
|
|
bfd8b38547 | ||
|
|
e6086f984e | ||
|
|
2e766cd3c9 | ||
|
|
48f53388fd | ||
|
|
6199f95c38 | ||
|
|
a6d84bd470 | ||
|
|
a11228a5ec | ||
|
|
7784e199af | ||
|
|
53895a4af2 | ||
|
|
354b938d60 | ||
|
|
643d8d3886 | ||
|
|
924c35d011 | ||
|
|
86163bf94c | ||
|
|
21b2d34432 | ||
|
|
98508a9c76 | ||
|
|
f8b232cc09 | ||
|
|
394b4b9967 | ||
|
|
1bea84eb3c | ||
|
|
26159138e0 | ||
|
|
1883009930 | ||
|
|
f1289c1e7d | ||
|
|
c3e4894243 | ||
|
|
2330dd97bb | ||
|
|
90b718122d | ||
|
|
5ca7ed0dc5 | ||
|
|
9bd03bfb76 | ||
|
|
07b7e270b8 | ||
|
|
f9dbbcdca2 | ||
|
|
b8968c5334 | ||
|
|
4f6b68ca93 |
+44
-23
@@ -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
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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_;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
@@ -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
@@ -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);
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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
@@ -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
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
@@ -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
Reference in New Issue
Block a user