diff --git a/artifacts/scripting/headers/define_extra.h b/artifacts/scripting/headers/define_extra.h index dc2894ee..ae0e4d04 100644 --- a/artifacts/scripting/headers/define_extra.h +++ b/artifacts/scripting/headers/define_extra.h @@ -349,7 +349,7 @@ #define Stereo16bit (soundstereo bwor sound16bit) #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 SoundVolumeHalf (0x40000000) #define SoundVolume75 (0x60000000) diff --git a/sfall/MiscPatches.cpp b/sfall/MiscPatches.cpp index 50415903..b1d8ffbb 100644 --- a/sfall/MiscPatches.cpp +++ b/sfall/MiscPatches.cpp @@ -125,48 +125,61 @@ fail: } } +static bool __fastcall SeeIsFront(TGameObj* source, TGameObj* target) { + long dir = source->rotation - TileDir(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 (ObjDist(source, target) <= (StatLevel(source, STAT_pe) * 3)); + } + return (dir == 0); // is directly in front +} + static void __declspec(naked) op_obj_can_see_obj_hook() { using namespace Fields; __asm { mov edi, [esp + 4]; // buf **ret_objStruct - test ebp, ebp; - jz onlyOnce; - xor ebp, ebp; + test ebp, ebp; // check only once + jz checkSee; + xor ebp, ebp; // for only once push edx; + push eax; mov edx, [edi - 8]; // target - push eax; // source - call can_see_; - test eax, eax; + mov ecx, eax; // source + call SeeIsFront; + xor ecx, ecx; + test al, al; pop eax; pop edx; - jz normal; -onlyOnce: + jnz checkSee; // can see + // vanilla behavior + push 0x10; + push edi; + call make_straight_path_; + retn 8; +checkSee: push obj_shoot_blocking_at_; // check hex objects func pointer push 0x20; // flags, 0x20 = check ShootThru push edi; call make_straight_path_func_; - // see through critter - mov ebx, [edi]; + mov edx, [edi - 8]; // target + mov ebx, [edi]; // blocking object test ebx, ebx; - jz skip; - cmp ebx, [edi - 8]; // target - jne noTarget; -skip: + jz isSee; // no blocking object + cmp ebx, edx; + jne checkObj; // object is not equal to target retn 8; -noTarget: +isSee: + mov [edi], edx; // fix for target with ShootThru flag + retn 8; +checkObj: mov eax, [ebx + protoId]; shr eax, 24; cmp eax, OBJ_TYPE_CRITTER; - je isCritter; + je continue; // see through critter retn 8; -isCritter: - mov [edi - 4], ebx; // replace source - mov dword ptr [esp], 0x456BAB; // continue - retn 8; -normal: // vanilla behavior - push 0x10; - push edi; - call make_straight_path_; +continue: + mov [edi - 4], ebx; // replace source with blocking object + mov dword ptr [esp], 0x456BAB; // repeat from the blocking object retn 8; } } @@ -432,7 +445,7 @@ static void DisablePipboyAlarmPatch() { static void ObjCanSeeShootThroughPatch() { 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); dlogr(" Done", DL_INIT); } diff --git a/sfall/Sound.cpp b/sfall/Sound.cpp index 2417a308..98ed9e7c 100644 --- a/sfall/Sound.cpp +++ b/sfall/Sound.cpp @@ -844,7 +844,7 @@ static void __declspec(naked) soundStartInterpret_hook() { mov eax, ebp; call soundSetFileIO_; 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; rawFile: xor edx, edx; @@ -858,10 +858,14 @@ rawFile: static const int SampleRate = 44100; // 44.1kHz +//void SetSoundSampleRate() { +// *ptr_sampleRate = SampleRate / 2; // Revert to 22kHz for secondary sound buffers +//} + void SoundInit() { // Set the sample rate for the primary sound buffer //SafeWrite32(0x44FDBC, SampleRate); - //LoadGameHook::OnAfterGameInit() += []() { *ptr_sampleRate = SampleRate / 2; }; // Revert to 22kHz for secondary sound buffers + // SetSoundSampleRate will be run after game initialization HookCall(0x44E816, gmovie_play_hook_pause); HookCall(0x44EA84, gmovie_play_hook_unpause); @@ -916,7 +920,7 @@ void SoundInit() { } } - // 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); }