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:
NovaRain
2020-03-31 21:51:41 +08:00
parent 29608bb51c
commit 0978769dfc
6 changed files with 31 additions and 17 deletions
+5 -1
View File
@@ -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
+1
View File
@@ -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
+4 -1
View File
@@ -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);
+7 -4
View File
@@ -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();
+9 -10
View File
@@ -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() {
+5 -1
View File
@@ -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];