mirror of
https://github.com/sfall-team/sfall.git
synced 2026-07-27 16:52:34 -07:00
Fixed loading savegame for "NPC turns into a container" bug fix
Added RadEffectsRemovalMsg option for radiation fixes. Some code/document correction.
This commit is contained in:
+5
-1
@@ -545,7 +545,7 @@ BoostScriptDialogLimit=0
|
||||
;Set the mode to 0 to disable the size check, 1 to apply to the PC only, 2 to apply to the PC and party members, or 3 to apply to all critters
|
||||
;Only the PC uses CritterInvSizeLimit. Other critters will use the unused stat (STAT_unused = 10) or have the size limit of 100 if the stat is not set
|
||||
;Add 4 to the mode to limit the weight check to used items only
|
||||
;You can use line number 542/543 in proto.msg and line number 35 in inventry.msg to set up custom messages for item size
|
||||
;You can use message number 542/543 in proto.msg and message number 35 in inventry.msg to set up custom messages for item size
|
||||
CritterInvSizeLimitMode=0
|
||||
CritterInvSizeLimit=100
|
||||
|
||||
@@ -662,6 +662,10 @@ DontTurnOffSneakIfYouRun=0
|
||||
;Set to 0 to disable switching. (Default is 3)
|
||||
UseWalkDistance=3
|
||||
|
||||
;Changes the message number in misc.msg used to display a message when you recover from radiation damage
|
||||
;Default is 3003 ('You feel better' message line)
|
||||
RadEffectsRemovalMsg=3003
|
||||
|
||||
;Set to 1 to display messages about radiation for the active geiger counter
|
||||
ActiveGeigerMsgs=1
|
||||
|
||||
|
||||
@@ -132,6 +132,7 @@ int arg1 - The pid of the weapon performing the attack. (May be -1 if the at
|
||||
critter arg2 - The attacker
|
||||
critter arg3 - The target
|
||||
int arg4 - The amount of damage
|
||||
int arg5 - Unused, always -1 (since sfall 4.1)
|
||||
|
||||
int ret1 - The pid of an object to override the attacking weapon with
|
||||
|
||||
|
||||
@@ -1879,11 +1879,13 @@ fix:
|
||||
}
|
||||
}
|
||||
|
||||
static long radEffectsMsgNum = 3003; // "You feel better" for removing effects
|
||||
|
||||
static void __declspec(naked) process_rads_hook() {
|
||||
__asm {
|
||||
test ebp, ebp;
|
||||
jg skip;
|
||||
mov esi, 999; // msg number
|
||||
mov esi, radEffectsMsgNum;
|
||||
mov [esp + 0x20 - 0x20 + 4], esi;
|
||||
skip:
|
||||
jmp fo::funcoffs::message_search_;
|
||||
@@ -3130,6 +3132,7 @@ void BugFixes::init()
|
||||
// Radiation fixes
|
||||
MakeCall(0x42D6C3, process_rads_hack, 1); // prevents player's death if a stat is less than 1 when removing radiation effects
|
||||
HookCall(0x42D67A, process_rads_hook); // fix for the same message being displayed when removing radiation effects
|
||||
radEffectsMsgNum = GetConfigInt("Misc", "RadEffectsRemovalMsg", radEffectsMsgNum);
|
||||
// Display messages about radiation for the active geiger counter
|
||||
if (GetConfigInt("Misc", "ActiveGeigerMsgs", 1)) {
|
||||
dlog("Applying active geiger counter messages patch.", DL_INIT);
|
||||
|
||||
@@ -80,6 +80,8 @@ static DWORD windowTop = 0;
|
||||
static HWND window;
|
||||
static DWORD windowStyle = WS_CAPTION | WS_BORDER | WS_MINIMIZEBOX;
|
||||
|
||||
static unsigned int windowData;
|
||||
|
||||
static DWORD ShaderVersion;
|
||||
|
||||
IDirect3D9* d3d9 = 0;
|
||||
@@ -1108,9 +1110,9 @@ HRESULT _stdcall FakeDirectDrawCreate2_Init(void*, IDirectDraw** b, void*) {
|
||||
} else {
|
||||
moveWindowKey[0] &= 0xFF;
|
||||
}
|
||||
int data = GetConfigInt("Graphics", "WindowData", 0);
|
||||
windowLeft = data >> 16;
|
||||
windowTop = data & 0xFFFF;
|
||||
windowData = GetConfigInt("Graphics", "WindowData", 0);
|
||||
windowLeft = windowData >> 16;
|
||||
windowTop = windowData & 0xFFFF;
|
||||
}
|
||||
|
||||
rcpres[0] = 1.0f / (float)gWidth;
|
||||
@@ -1180,7 +1182,8 @@ void Graphics::init() {
|
||||
void Graphics::exit() {
|
||||
if (Graphics::mode) {
|
||||
if (Graphics::mode == 5) {
|
||||
SetConfigInt("Graphics", "WindowData", windowTop | (windowLeft << 16));
|
||||
unsigned int data = windowTop | (windowLeft << 16);
|
||||
if (data != windowData) SetConfigInt("Graphics", "WindowData", data);
|
||||
}
|
||||
if (titlesBuffer) delete[] titlesBuffer;
|
||||
CoUninitialize();
|
||||
|
||||
@@ -11,48 +11,47 @@ namespace sfall
|
||||
static bool registerHookDeathAnim1 = false;
|
||||
static bool registerHookDeathAnim2 = false;
|
||||
|
||||
static DWORD __fastcall CalcDeathAnimHook_Script(register DWORD damage, fo::GameObject* target, fo::GameObject* attacker, fo::GameObject* weapon, int animation, int hitBack) {
|
||||
|
||||
static DWORD __fastcall CalcDeathAnimHook_Script(DWORD damage, fo::GameObject* target, fo::GameObject* attacker, fo::GameObject* weapon, int animation, int hitBack) {
|
||||
BeginHook();
|
||||
argCount = 5; // was 4
|
||||
|
||||
args[1] = (DWORD)attacker;
|
||||
args[2] = (DWORD)target;
|
||||
args[3] = damage;
|
||||
args[4] = -1;
|
||||
|
||||
// weapon_ptr
|
||||
args[0] = (weapon) ? weapon->protoId : -1; // attack is unarmed
|
||||
|
||||
bool createNewObj = false;
|
||||
if (registerHookDeathAnim1) {
|
||||
args[4] = -1; // set 'no anim' for combined hooks use
|
||||
RunHookScript(HOOK_DEATHANIM1);
|
||||
if (cRet > 0) {
|
||||
register DWORD pid = rets[0];
|
||||
args[0] = pid;
|
||||
DWORD pid = rets[0];
|
||||
args[0] = pid; // replace for HOOK_DEATHANIM2
|
||||
fo::GameObject* object = nullptr;
|
||||
if (fo::func::obj_pid_new((fo::GameObject*)&object, pid) != -1) { // create new object
|
||||
createNewObj = true;
|
||||
weapon = object; // replace pointer to created object
|
||||
weapon = object; // replace pointer with newly created weapon object
|
||||
}
|
||||
cRet = 0; // reset rets from HOOK_DEATHANIM1
|
||||
}
|
||||
}
|
||||
|
||||
long animDeath = fo::func::pick_death(attacker, target, weapon, damage, animation, hitBack); // vanilla pick death
|
||||
DWORD animDeath = fo::func::pick_death(attacker, target, weapon, damage, animation, hitBack); // vanilla pick death
|
||||
|
||||
if (registerHookDeathAnim2) {
|
||||
//argCount = 5;
|
||||
args[4] = animDeath;
|
||||
RunHookScript(HOOK_DEATHANIM2);
|
||||
}
|
||||
|
||||
DWORD result = (cRet > 0) ? rets[0] : animDeath;
|
||||
if (cRet > 0) animDeath = rets[0];
|
||||
}
|
||||
EndHook();
|
||||
|
||||
if (createNewObj) fo::func::obj_erase_object(weapon, 0); // delete created object
|
||||
|
||||
return result;
|
||||
return animDeath;
|
||||
}
|
||||
|
||||
static void __declspec(naked) CalcDeathAnimHook() {
|
||||
|
||||
@@ -118,11 +118,15 @@ static void __declspec(naked) queue_add_hack() {
|
||||
using namespace fo;
|
||||
using namespace Fields;
|
||||
__asm {
|
||||
// engine code
|
||||
mov [edx + 8], edi; // queue.object
|
||||
mov [edx], esi; // queue.time
|
||||
//
|
||||
//---
|
||||
cmp ds:[FO_VAR_loadingGame], 1; // don't change the object ID when loading a saved game (e.g. fix: NPC turns into a container)
|
||||
je skip;
|
||||
test edi, edi;
|
||||
jnz fix;
|
||||
skip:
|
||||
retn;
|
||||
fix:
|
||||
mov eax, [edi + protoId];
|
||||
|
||||
Reference in New Issue
Block a user