Tweaked the field of view check in ObjCanSeeObj_ShootThru_Fix

And fixed a bug when the target critter has the ShootTrhu flag set
(cannot be seen by the source)

Minor edits to some comments in previous commit.
This commit is contained in:
NovaRain
2020-09-02 14:21:38 +08:00
parent 0945382369
commit 3df322b80e
3 changed files with 41 additions and 28 deletions
+1 -1
View File
@@ -467,7 +467,7 @@
#define Stereo16bit (soundstereo bwor sound16bit) #define Stereo16bit (soundstereo bwor sound16bit)
#define Stereo16bitLoop (soundstereo bwor sound16bit bwor soundloop) #define Stereo16bitLoop (soundstereo bwor sound16bit bwor soundloop)
// Volume reduction: 0x0000XXXX - min, 0x7FFFXXXX - mute // Adjust/reduce volume: 0x0000XXXX - max volume, 0x7FFFXXXX - mute
#define SoundVolume25 (0x20000000) #define SoundVolume25 (0x20000000)
#define SoundVolumeHalf (0x40000000) #define SoundVolumeHalf (0x40000000)
#define SoundVolume75 (0x60000000) #define SoundVolume75 (0x60000000)
+38 -25
View File
@@ -132,49 +132,62 @@ fail:
} }
} }
static bool __fastcall SeeIsFront(fo::GameObject* source, fo::GameObject* target) {
long dir = source->rotation - fo::func::tile_dir(source->tile, target->tile);
if (dir < 0) dir = -dir;
if (dir == 1 || dir == 5) { // peripheral/side vision, reduce the range for seeing through (3x instead of 5x)
return (fo::func::obj_dist(source, target) <= (fo::func::stat_level(source, fo::STAT_pe) * 3));
}
return (dir == 0); // is directly in front
}
static void __declspec(naked) op_obj_can_see_obj_hook() { static void __declspec(naked) op_obj_can_see_obj_hook() {
using namespace fo; using namespace fo;
using namespace Fields; using namespace Fields;
__asm { __asm {
mov edi, [esp + 4]; // buf **ret_objStruct mov edi, [esp + 4]; // buf **ret_objStruct
test ebp, ebp; test ebp, ebp; // check only once
jz onlyOnce; jz checkSee;
xor ebp, ebp; xor ebp, ebp; // for only once
push edx; push edx;
push eax;
mov edx, [edi - 8]; // target mov edx, [edi - 8]; // target
push eax; // source mov ecx, eax; // source
call fo::funcoffs::can_see_; call SeeIsFront;
test eax, eax; xor ecx, ecx;
test al, al;
pop eax; pop eax;
pop edx; pop edx;
jz normal; jnz checkSee; // can see
onlyOnce: // vanilla behavior
push 0x10;
push edi;
call fo::funcoffs::make_straight_path_;
retn 8;
checkSee:
push fo::funcoffs::obj_shoot_blocking_at_; // check hex objects func pointer push fo::funcoffs::obj_shoot_blocking_at_; // check hex objects func pointer
push 0x20; // flags, 0x20 = check ShootThru push 0x20; // flags, 0x20 = check ShootThru
push edi; push edi;
call fo::funcoffs::make_straight_path_func_; call fo::funcoffs::make_straight_path_func_;
// see through critter mov edx, [edi - 8]; // target
mov ebx, [edi]; mov ebx, [edi]; // blocking object
test ebx, ebx; test ebx, ebx;
jz skip; jz isSee; // no blocking object
cmp ebx, [edi - 8]; // target cmp ebx, edx;
jne noTarget; jne checkObj; // object is not equal to target
skip:
retn 8; retn 8;
noTarget: isSee:
mov [edi], edx; // fix for target with ShootThru flag
retn 8;
checkObj:
mov eax, [ebx + protoId]; mov eax, [ebx + protoId];
shr eax, 24; shr eax, 24;
cmp eax, OBJ_TYPE_CRITTER; cmp eax, OBJ_TYPE_CRITTER;
je isCritter; je continue; // see through critter
retn 8; retn 8;
isCritter: continue:
mov [edi - 4], ebx; // replace source mov [edi - 4], ebx; // replace source with blocking object
mov dword ptr [esp], 0x456BAB; // continue mov dword ptr [esp], 0x456BAB; // repeat from the blocking object
retn 8;
normal: // vanilla behavior
push 0x10;
push edi;
call fo::funcoffs::make_straight_path_;
retn 8; retn 8;
} }
} }
@@ -514,7 +527,7 @@ static void DisablePipboyAlarmPatch() {
static void ObjCanSeeShootThroughPatch() { static void ObjCanSeeShootThroughPatch() {
if (GetConfigInt("Misc", "ObjCanSeeObj_ShootThru_Fix", 0)) { if (GetConfigInt("Misc", "ObjCanSeeObj_ShootThru_Fix", 0)) {
dlog("Applying obj_can_see_obj fix for critters and ShootThru objects.", DL_INIT); dlog("Applying obj_can_see_obj fix for seeing through critters and ShootThru objects.", DL_INIT);
HookCall(0x456BC6, op_obj_can_see_obj_hook); HookCall(0x456BC6, op_obj_can_see_obj_hook);
dlogr(" Done", DL_INIT); dlogr(" Done", DL_INIT);
} }
+2 -2
View File
@@ -832,7 +832,7 @@ static void __declspec(naked) soundStartInterpret_hook() {
mov eax, ebp; mov eax, ebp;
call fo::funcoffs::soundSetFileIO_; call fo::funcoffs::soundSetFileIO_;
pop ecx; pop ecx;
mov bx, [esp + 0x18 - 0x18 + 4+2]; // get volume adjustment: 0 - max, 32767 - mute mov bx, [esp + 0x18 - 0x18 + 4+2]; // get volume adjustment: 0 - max volume, 32767 - mute
and bx, ~0x8000; and bx, ~0x8000;
rawFile: rawFile:
xor edx, edx; xor edx, edx;
@@ -906,7 +906,7 @@ void Sound::init() {
} }
} }
// Support for ACM audio file playback and volume adjustment for the soundplay script function // Support for ACM audio file playback and volume control for the soundplay script function
HookCall(0x4661B3, soundStartInterpret_hook); HookCall(0x4661B3, soundStartInterpret_hook);
} }