diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 00000000..51ef58eb --- /dev/null +++ b/.travis.yml @@ -0,0 +1,15 @@ +language: cpp +os: linux +dist: focal +matrix: + include: + - env: TARGET=release_linux-amd64-librw_gl3_glfw-oal + - env: TARGET=debug_linux-amd64-librw_gl3_glfw-oal +script: + - sudo apt-get update + - sudo apt-get -y install linux-libc-dev libopenal-dev libglew-dev libglfw3-dev libsndfile1-dev libmpg123-dev gcc-8-multilib g++-8-multilib + - mkdir -p "$TRAVIS_BUILD_DIR/build" + - cd "$TRAVIS_BUILD_DIR" + - ./premake5Linux --with-librw gmake2 + - cd build + - CC=gcc-8 CXX=g++-8 make config=$TARGET -j4 verbose=1 diff --git a/eax/eax.h b/eax/eax.h index 0e2201db..b2210936 100644 --- a/eax/eax.h +++ b/eax/eax.h @@ -12,7 +12,7 @@ extern "C" { #endif // __cplusplus -#ifndef OPENAL +#ifndef AUDIO_OAL #include /* @@ -49,13 +49,9 @@ extern "C" { typedef void (CDECL *LPGETCURRENTVERSION)(LPDWORD major, LPDWORD minor); -#else // OPENAL -#ifndef _WIN32 +#else // AUDIO_OAL #include #include -#else - #include -#endif #ifndef GUID_DEFINED #define GUID_DEFINED diff --git a/gamefiles/models/menu.txd b/gamefiles/models/menu.txd index f617bcf8..1ffe750e 100644 Binary files a/gamefiles/models/menu.txd and b/gamefiles/models/menu.txd differ diff --git a/librw b/librw index 661feeab..84c582c1 160000 --- a/librw +++ b/librw @@ -1 +1 @@ -Subproject commit 661feeabf4a4f0a8b0bee23b53ba557a14352d00 +Subproject commit 84c582c1d7a64a213523b8e4c8211f8b7a4fdcd1 diff --git a/premake5.lua b/premake5.lua index 44b8b576..6a27c5af 100644 --- a/premake5.lua +++ b/premake5.lua @@ -23,6 +23,22 @@ else Librw = os.getenv("LIBRW") or "librw" end +function getsys(a) + if a == 'windows' then + return 'win' + end + return a +end + +function getarch(a) + if a == 'x86_64' then + return 'amd64' + elseif a == 'ARM' then + return 'arm' + end + return a +end + workspace "reVC" language "C++" configurations { "Debug", "Release" } @@ -35,11 +51,16 @@ workspace "reVC" "win-x86-RW33_d3d8-mss", "win-x86-librw_d3d9-mss", "win-x86-librw_gl3_glfw-mss", + "win-x86-RW33_d3d8-oal", + "win-x86-librw_d3d9-oal", + "win-x86-librw_gl3_glfw-oal", } filter { "system:linux" } platforms { "linux-x86-librw_gl3_glfw-oal", + "linux-amd64-librw_gl3_glfw-oal", + "linux-arm-librw_gl3_glfw-oal", } filter "configurations:Debug" @@ -58,6 +79,12 @@ workspace "reVC" filter { "platforms:*x86*" } architecture "x86" + filter { "platforms:*amd64*" } + architecture "amd64" + + filter { "platforms:*arm*" } + architecture "ARM" + filter { "platforms:*librw_d3d9*" } defines { "RW_D3D9" } if(not _OPTIONS["with-librw"]) then @@ -68,17 +95,12 @@ workspace "reVC" defines { "RW_GL3" } includedirs { path.join(_OPTIONS["glfwdir"], "include") } includedirs { path.join(_OPTIONS["glewdir"], "include") } + if(not _OPTIONS["with-librw"]) then + libdirs { path.join(Librw, "lib/%{getsys(cfg.system)}-%{getarch(cfg.architecture)}-gl3/%{cfg.buildcfg}") } + end filter "platforms:win*librw_gl3_glfw*" defines { "GLEW_STATIC" } - if(not _OPTIONS["with-librw"]) then - libdirs { path.join(Librw, "lib/win-x86-gl3/%{cfg.buildcfg}") } - end - - filter "platforms:linux*librw_gl3_glfw*" - if(not _OPTIONS["with-librw"]) then - libdirs { path.join(Librw, "lib/linux-x86-gl3/%{cfg.buildcfg}") } - end filter {} @@ -164,12 +186,16 @@ project "reVC" includedirs { "src/weapons" } includedirs { "src/extras" } includedirs { "eax" } - - includedirs { "milessdk/include" } - includedirs { "eax" } - - libdirs { "milessdk/lib" } + filter "platforms:*mss" + defines { "AUDIO_MSS" } + includedirs { "milessdk/include" } + libdirs { "milessdk/lib" } + + filter "platforms:*oal" + defines { "AUDIO_OAL" } + + filter {} if(os.getenv("GTA_VC_RE_DIR")) then setpaths("$(GTA_VC_RE_DIR)/", "%(cfg.buildtarget.name)", "") end @@ -181,9 +207,15 @@ project "reVC" characterset ("MBCS") targetextension ".exe" - filter "platforms:linux*" - targetextension ".elf" - defines { "OPENAL" } + filter "platforms:win*oal" + includedirs { "openal-soft/include" } + includedirs { "libsndfile/include" } + includedirs { "mpg123/include" } + libdirs { "openal-soft/libs/Win32" } + libdirs { "libsndfile/lib" } + libdirs { "mpg123/lib" } + + filter "platforms:linux*oal" links { "openal", "mpg123", "sndfile", "pthread" } filter "platforms:*RW33*" diff --git a/src/animation/AnimBlendAssocGroup.cpp b/src/animation/AnimBlendAssocGroup.cpp index c5711fda..83c1742a 100644 --- a/src/animation/AnimBlendAssocGroup.cpp +++ b/src/animation/AnimBlendAssocGroup.cpp @@ -104,7 +104,7 @@ strcmpIgnoringDigits(const char *s1, const char *s2) c2 = toupper(c2); #endif - if(c1 != c2) + if(c1 && c2 && c1 != c2) return false; } } diff --git a/src/animation/AnimBlendAssociation.h b/src/animation/AnimBlendAssociation.h index 90e0cfd9..f6d98fc3 100644 --- a/src/animation/AnimBlendAssociation.h +++ b/src/animation/AnimBlendAssociation.h @@ -84,7 +84,8 @@ public: void SetRun(void) { flags |= ASSOC_RUNNING; } - inline float GetTimeLeft() { return hierarchy->totalLength - currentTime; } + float GetTimeLeft() { return hierarchy->totalLength - currentTime; } + float GetProgress() { return currentTime / hierarchy->totalLength; } static CAnimBlendAssociation *FromLink(CAnimBlendLink *l) { return (CAnimBlendAssociation*)((uint8*)l - offsetof(CAnimBlendAssociation, link)); diff --git a/src/animation/AnimManager.cpp b/src/animation/AnimManager.cpp index 55bd7d53..16207f54 100644 --- a/src/animation/AnimManager.cpp +++ b/src/animation/AnimManager.cpp @@ -134,13 +134,13 @@ AnimAssocDesc aStdAnimDescs[] = { { ANIM_DRIVE_LOW_R, ASSOC_DELETEFADEDOUT | ASSOC_PARTIAL | ASSOC_DRIVING }, { ANIM_DRIVEBY_L, ASSOC_DELETEFADEDOUT | ASSOC_PARTIAL | ASSOC_DRIVING }, { ANIM_DRIVEBY_R, ASSOC_DELETEFADEDOUT | ASSOC_PARTIAL | ASSOC_DRIVING }, - { ANIM_DRIVEBY_L_L, ASSOC_DELETEFADEDOUT | ASSOC_PARTIAL | ASSOC_DRIVING }, - { ANIM_DRIVEBY_L_R, ASSOC_DELETEFADEDOUT | ASSOC_PARTIAL | ASSOC_DRIVING }, + { ANIM_DRIVEBY_LOW_L, ASSOC_DELETEFADEDOUT | ASSOC_PARTIAL | ASSOC_DRIVING }, + { ANIM_DRIVEBY_LOW_R, ASSOC_DELETEFADEDOUT | ASSOC_PARTIAL | ASSOC_DRIVING }, { ANIM_CAR_LB, ASSOC_DELETEFADEDOUT | ASSOC_PARTIAL | ASSOC_DRIVING }, { ANIM_DRIVE_BOAT, ASSOC_DELETEFADEDOUT | ASSOC_DRIVING }, { ANIM_DRIVE_BOAT_L, ASSOC_DELETEFADEDOUT | ASSOC_PARTIAL | ASSOC_DRIVING }, { ANIM_DRIVE_BOAT_R, ASSOC_DELETEFADEDOUT | ASSOC_PARTIAL | ASSOC_DRIVING }, - { ANIM_DRIVE_BOAT_BACK, ASSOC_DELETEFADEDOUT | ASSOC_PARTIAL | ASSOC_DRIVING }, + { ANIM_BOAT_LB, ASSOC_DELETEFADEDOUT | ASSOC_PARTIAL | ASSOC_DRIVING }, { ANIM_BIKE_PICKUP_R, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL }, { ANIM_BIKE_PICKUP_L, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL }, { ANIM_BIKE_PULLUP_R, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL }, @@ -899,70 +899,71 @@ char const* aChainsawStrafeRightAnimations[] = { }; - +#define awc(a) ARRAY_SIZE(a), a const AnimAssocDefinition CAnimManager::ms_aAnimAssocDefinitions[NUM_ANIM_ASSOC_GROUPS] = { - { "man", "ped", MI_COP, 173, aStdAnimations, aStdAnimDescs }, - { "van", "van", MI_COP, 8, aVanAnimations, aVanAnimDescs }, - { "coach", "coach", MI_COP, 5, aCoachAnimations, aCoachAnimDescs }, - { "bikes", "bikes", MI_COP, 18, aBikesAnimations, aBikeAnimDescs }, - { "bikev", "bikev", MI_COP, 18, aBikevAnimations, aBikeAnimDescs }, - { "bikeh", "bikeh", MI_COP, 18, aBikehAnimations, aBikeAnimDescs }, - { "biked", "biked", MI_COP, 18, aBikedAnimations, aBikeAnimDescs }, - { "unarmed", "ped", MI_COP, 3, aUnarmedAnimations, aMeleeAnimDescs }, - { "screwdrv", "ped", MI_COP, 5, aScrewdriverAnimations, aMeleeAnimDescs }, - { "knife", "knife", MI_COP, 5, aKnifeAnimations, aMeleeAnimDescs }, - { "baseball", "baseball", MI_COP, 5, aBaseballbatAnimations, aSwingAnimDescs }, - { "golfclub", "baseball", MI_COP, 5, aGolfclubAnimations, aSwingAnimDescs }, - { "chainsaw", "chainsaw", MI_COP, 3, aChainsawAnimations, aMeleeAnimDescs }, - { "python", "python", MI_COP, 4, aPythonAnimations, aWeaponAnimDescs }, - { "colt45", "colt45", MI_COP, 5, aColtAnimations, aWeaponAnimDescs }, - { "shotgun", "shotgun", MI_COP, 2, aShotgunAnimations, aWeaponAnimDescs }, - { "buddy", "buddy", MI_COP, 2, aBuddyAnimations, aWeaponAnimDescs }, - { "tec", "tec", MI_COP, 4, aTecAnimations, aWeaponAnimDescs }, - { "uzi", "uzi", MI_COP, 4, aUziAnimations, aWeaponAnimDescs }, - { "rifle", "rifle", MI_COP, 4, aRifleAnimations, aWeaponAnimDescs }, - { "m60", "m60", MI_COP, 3, aM60Animations, aWeaponAnimDescs }, - { "sniper", "sniper", MI_COP, 1, aSniperAnimations, aWeaponAnimDescs }, - { "grenade", "grenade", MI_COP, 3, aThrowAnimations, aWeaponAnimDescs }, - { "flame", "flame", MI_COP, 1, aFlamethrowerAnimations, aWeaponAnimDescs }, - { "medic", "medic", MI_COP, 1, aMedicAnimations, aMedicAnimDescs }, - { "sunbathe", "sunbathe", MI_COP, 1, aSunbatheAnimations, aSunbatheAnimDescs }, - { "playidles", "playidles", MI_COP, 4, aPlayerIdleAnimations, aPlayerIdleAnimDescs }, - { "riot", "riot", MI_COP, 7, aRiotAnimations, aRiotAnimDescs }, - { "strip", "strip", MI_COP, 7, aStripAnimations, aStripAnimDescs }, - { "lance", "lance", MI_COP, 1, aLanceAnimations, aSunbatheAnimDescs }, - { "player", "ped", MI_COP, 5, aPlayerAnimations, aStdAnimDescs }, - { "playerrocket", "ped", MI_COP, 5, aPlayerWithRocketAnimations, aStdAnimDescs }, - { "player1armed", "ped", MI_COP, 5, aPlayer1ArmedAnimations, aStdAnimDescs }, - { "player2armed", "ped", MI_COP, 5, aPlayer2ArmedAnimations, aStdAnimDescs }, - { "playerBBBat", "ped", MI_COP, 5, aPlayerBBBatAnimations, aStdAnimDescs }, - { "playercsaw", "ped", MI_COP, 5, aPlayerChainsawAnimations, aStdAnimDescs }, - { "shuffle", "ped", MI_COP, 4, aShuffleAnimations, aStdAnimDescs }, - { "oldman", "ped", MI_COP, 4, aOldAnimations, aStdAnimDescs }, - { "gang1", "ped", MI_COP, 4, aGang1Animations, aStdAnimDescs }, - { "gang2", "ped", MI_COP, 4, aGang2Animations, aStdAnimDescs }, - { "fatman", "ped", MI_COP, 4, aFatAnimations, aStdAnimDescs }, - { "oldfatman", "ped", MI_COP, 4, aOldFatAnimations, aStdAnimDescs }, - { "jogger", "ped", MI_COP, 4, aJoggerAnimations, aStdAnimDescs }, - { "woman", "ped", MI_COP, 4, aStdWomanAnimations, aStdAnimDescs }, - { "shopping", "ped", MI_COP, 4, aWomanShopAnimations, aStdAnimDescs }, - { "busywoman", "ped", MI_COP, 4, aBusyWomanAnimations, aStdAnimDescs }, - { "sexywoman", "ped", MI_COP, 4, aSexyWomanAnimations, aStdAnimDescs }, - { "fatwoman", "ped", MI_COP, 4, aFatWomanAnimations, aStdAnimDescs }, - { "oldwoman", "ped", MI_COP, 4, aOldWomanAnimations, aStdAnimDescs }, - { "jogwoman", "ped", MI_COP, 4, aJoggerWomanAnimations, aStdAnimDescs }, - { "panicchunky", "ped", MI_COP, 4, aPanicChunkyAnimations, aStdAnimDescs }, - { "skate", "skate", MI_COP, 4, aSkateAnimations, aStdAnimDescs }, - { "playerback", "ped", MI_COP, 5, aPlayerStrafeBackAnimations, aStdAnimDescs }, - { "playerleft", "ped", MI_COP, 5, aPlayerStrafeLeftAnimations, aStdAnimDescsSide }, - { "playerright", "ped", MI_COP, 5, aPlayerStrafeRightAnimations, aStdAnimDescsSide }, - { "rocketback", "ped", MI_COP, 5, aRocketStrafeBackAnimations, aStdAnimDescs }, - { "rocketleft", "ped", MI_COP, 5, aRocketStrafeLeftAnimations, aStdAnimDescsSide }, - { "rocketright", "ped", MI_COP, 5, aRocketStrafeRightAnimations, aStdAnimDescsSide }, - { "csawback", "ped", MI_COP, 5, aChainsawStrafeBackAnimations, aStdAnimDescs }, - { "csawleft", "ped", MI_COP, 5, aChainsawStrafeLeftAnimations, aStdAnimDescsSide }, - { "csawright", "ped", MI_COP, 5, aChainsawStrafeRightAnimations, aStdAnimDescsSide }, + { "man", "ped", MI_COP, awc(aStdAnimations), aStdAnimDescs }, + { "van", "van", MI_COP, awc(aVanAnimations), aVanAnimDescs }, + { "coach", "coach", MI_COP, awc(aCoachAnimations), aCoachAnimDescs }, + { "bikes", "bikes", MI_COP, awc(aBikesAnimations), aBikeAnimDescs }, + { "bikev", "bikev", MI_COP, awc(aBikevAnimations), aBikeAnimDescs }, + { "bikeh", "bikeh", MI_COP, awc(aBikehAnimations), aBikeAnimDescs }, + { "biked", "biked", MI_COP, awc(aBikedAnimations), aBikeAnimDescs }, + { "unarmed", "ped", MI_COP, awc(aUnarmedAnimations), aMeleeAnimDescs }, + { "screwdrv", "ped", MI_COP, awc(aScrewdriverAnimations), aMeleeAnimDescs }, + { "knife", "knife", MI_COP, awc(aKnifeAnimations), aMeleeAnimDescs }, + { "baseball", "baseball", MI_COP, awc(aBaseballbatAnimations), aSwingAnimDescs }, + { "golfclub", "baseball", MI_COP, awc(aGolfclubAnimations), aSwingAnimDescs }, + { "chainsaw", "chainsaw", MI_COP, awc(aChainsawAnimations), aMeleeAnimDescs }, + { "python", "python", MI_COP, awc(aPythonAnimations), aWeaponAnimDescs }, + { "colt45", "colt45", MI_COP, awc(aColtAnimations), aWeaponAnimDescs }, + { "shotgun", "shotgun", MI_COP, awc(aShotgunAnimations), aWeaponAnimDescs }, + { "buddy", "buddy", MI_COP, awc(aBuddyAnimations), aWeaponAnimDescs }, + { "tec", "tec", MI_COP, awc(aTecAnimations), aWeaponAnimDescs }, + { "uzi", "uzi", MI_COP, awc(aUziAnimations), aWeaponAnimDescs }, + { "rifle", "rifle", MI_COP, awc(aRifleAnimations), aWeaponAnimDescs }, + { "m60", "m60", MI_COP, awc(aM60Animations), aWeaponAnimDescs }, + { "sniper", "sniper", MI_COP, awc(aSniperAnimations), aWeaponAnimDescs }, + { "grenade", "grenade", MI_COP, awc(aThrowAnimations), aWeaponAnimDescs }, + { "flame", "flame", MI_COP, awc(aFlamethrowerAnimations), aWeaponAnimDescs }, + { "medic", "medic", MI_COP, awc(aMedicAnimations), aMedicAnimDescs }, + { "sunbathe", "sunbathe", MI_COP, 1, aSunbatheAnimations, aSunbatheAnimDescs }, // NB: not using awc here! + { "playidles", "playidles", MI_COP, awc(aPlayerIdleAnimations), aPlayerIdleAnimDescs }, + { "riot", "riot", MI_COP, awc(aRiotAnimations), aRiotAnimDescs }, + { "strip", "strip", MI_COP, awc(aStripAnimations), aStripAnimDescs }, + { "lance", "lance", MI_COP, awc(aLanceAnimations), aSunbatheAnimDescs }, + { "player", "ped", MI_COP, awc(aPlayerAnimations), aStdAnimDescs }, + { "playerrocket", "ped", MI_COP, awc(aPlayerWithRocketAnimations), aStdAnimDescs }, + { "player1armed", "ped", MI_COP, awc(aPlayer1ArmedAnimations), aStdAnimDescs }, + { "player2armed", "ped", MI_COP, awc(aPlayer2ArmedAnimations), aStdAnimDescs }, + { "playerBBBat", "ped", MI_COP, awc(aPlayerBBBatAnimations), aStdAnimDescs }, + { "playercsaw", "ped", MI_COP, awc(aPlayerChainsawAnimations), aStdAnimDescs }, + { "shuffle", "ped", MI_COP, awc(aShuffleAnimations), aStdAnimDescs }, + { "oldman", "ped", MI_COP, awc(aOldAnimations), aStdAnimDescs }, + { "gang1", "ped", MI_COP, awc(aGang1Animations), aStdAnimDescs }, + { "gang2", "ped", MI_COP, awc(aGang2Animations), aStdAnimDescs }, + { "fatman", "ped", MI_COP, awc(aFatAnimations), aStdAnimDescs }, + { "oldfatman", "ped", MI_COP, awc(aOldFatAnimations), aStdAnimDescs }, + { "jogger", "ped", MI_COP, awc(aJoggerAnimations), aStdAnimDescs }, + { "woman", "ped", MI_COP, awc(aStdWomanAnimations), aStdAnimDescs }, + { "shopping", "ped", MI_COP, awc(aWomanShopAnimations), aStdAnimDescs }, + { "busywoman", "ped", MI_COP, awc(aBusyWomanAnimations), aStdAnimDescs }, + { "sexywoman", "ped", MI_COP, awc(aSexyWomanAnimations), aStdAnimDescs }, + { "fatwoman", "ped", MI_COP, awc(aFatWomanAnimations), aStdAnimDescs }, + { "oldwoman", "ped", MI_COP, awc(aOldWomanAnimations), aStdAnimDescs }, + { "jogwoman", "ped", MI_COP, awc(aJoggerWomanAnimations), aStdAnimDescs }, + { "panicchunky", "ped", MI_COP, awc(aPanicChunkyAnimations), aStdAnimDescs }, + { "skate", "skate", MI_COP, awc(aSkateAnimations), aStdAnimDescs }, + { "playerback", "ped", MI_COP, awc(aPlayerStrafeBackAnimations), aStdAnimDescs }, + { "playerleft", "ped", MI_COP, awc(aPlayerStrafeLeftAnimations), aStdAnimDescsSide }, + { "playerright", "ped", MI_COP, awc(aPlayerStrafeRightAnimations), aStdAnimDescsSide }, + { "rocketback", "ped", MI_COP, awc(aRocketStrafeBackAnimations), aStdAnimDescs }, + { "rocketleft", "ped", MI_COP, awc(aRocketStrafeLeftAnimations), aStdAnimDescsSide }, + { "rocketright", "ped", MI_COP, awc(aRocketStrafeRightAnimations), aStdAnimDescsSide }, + { "csawback", "ped", MI_COP, awc(aChainsawStrafeBackAnimations), aStdAnimDescs }, + { "csawleft", "ped", MI_COP, awc(aChainsawStrafeLeftAnimations), aStdAnimDescsSide }, + { "csawright", "ped", MI_COP, awc(aChainsawStrafeRightAnimations), aStdAnimDescsSide }, }; +#undef awc void CAnimManager::Initialise(void) diff --git a/src/animation/AnimationId.h b/src/animation/AnimationId.h index 9fe0cb0e..a84aa3e8 100644 --- a/src/animation/AnimationId.h +++ b/src/animation/AnimationId.h @@ -118,13 +118,13 @@ enum AnimationId ANIM_DRIVE_LOW_R, ANIM_DRIVEBY_L, ANIM_DRIVEBY_R, - ANIM_DRIVEBY_L_L, // TODO: is this LOW? - ANIM_DRIVEBY_L_R, + ANIM_DRIVEBY_LOW_L, + ANIM_DRIVEBY_LOW_R, ANIM_CAR_LB, ANIM_DRIVE_BOAT, ANIM_DRIVE_BOAT_L, ANIM_DRIVE_BOAT_R, - ANIM_DRIVE_BOAT_BACK, + ANIM_BOAT_LB, ANIM_BIKE_PICKUP_R, ANIM_BIKE_PICKUP_L, diff --git a/src/audio/AudioCollision.cpp b/src/audio/AudioCollision.cpp index ecd0299c..55d64714 100644 --- a/src/audio/AudioCollision.cpp +++ b/src/audio/AudioCollision.cpp @@ -70,36 +70,36 @@ cAudioManager::GetCollisionOneShotRatio(int32 a, float b) const case SURFACE_DEFAULT: case SURFACE_TARMAC: case SURFACE_PAVEMENT: - case SURFACE_STONE: - case SURFACE_BOLLARD: result = GetCollisionRatio(b, 10.f, 60.f, 50.f); break; + case SURFACE_STEEP_CLIFF: + case SURFACE_TRANSPARENT_STONE: result = GetCollisionRatio(b, 10.f, 60.f, 50.f); break; case SURFACE_GRASS: - case SURFACE_LOOSE30: result = GetCollisionRatio(b, 0.f, 2.f, 2.f); break; - case SURFACE_DIRT: result = GetCollisionRatio(b, 0.f, 2.f, 2.f); break; - case SURFACE_DIRTTRACK: result = GetCollisionRatio(b, 0.f, 2.f, 2.f); break; - case SURFACE_METAL6: result = GetCollisionRatio(b, 6.f, 50.f, 44.f); break; + case SURFACE_CARDBOARDBOX: result = GetCollisionRatio(b, 0.f, 2.f, 2.f); break; + case SURFACE_GRAVEL: result = GetCollisionRatio(b, 0.f, 2.f, 2.f); break; + case SURFACE_MUD_DRY: result = GetCollisionRatio(b, 0.f, 2.f, 2.f); break; + case SURFACE_CAR: result = GetCollisionRatio(b, 6.f, 50.f, 44.f); break; case SURFACE_GLASS: result = GetCollisionRatio(b, 0.1f, 10.f, 9.9f); break; - case SURFACE_SCAFFOLD: - case SURFACE_STEEL: result = GetCollisionRatio(b, 30.f, 130.f, 100.f); break; - case SURFACE_METAL_DOOR: result = GetCollisionRatio(b, 20.f, 100.f, 80.f); break; - case SURFACE_BILLBOARD: result = GetCollisionRatio(b, 0.f, 4.f, 4.f); break; - case SURFACE_METAL_POLE: - case SURFACE_GATE: result = GetCollisionRatio(b, 1.f, 10.f, 9.f); break; - case SURFACE_STREET_LIGHT: result = GetCollisionRatio(b, 1.f, 10.f, 9.f); break; - case SURFACE_METAL14: result = GetCollisionRatio(b, 1.f, 15.f, 14.f); break; - case SURFACE_METAL15: result = GetCollisionRatio(b, 8.f, 50.f, 42.f); break; - case SURFACE_METAL_FENCE: result = GetCollisionRatio(b, 0.1f, 10.f, 9.9f); break; - case SURFACE_FLESH: result = GetCollisionRatio(b, 0.f, 20.f, 20.f); break; + case SURFACE_TRANSPARENT_CLOTH: + case SURFACE_THICK_METAL_PLATE: result = GetCollisionRatio(b, 30.f, 130.f, 100.f); break; + case SURFACE_GARAGE_DOOR: result = GetCollisionRatio(b, 20.f, 100.f, 80.f); break; + case SURFACE_CAR_PANEL: result = GetCollisionRatio(b, 0.f, 4.f, 4.f); break; + case SURFACE_SCAFFOLD_POLE: + case SURFACE_METAL_GATE: result = GetCollisionRatio(b, 1.f, 10.f, 9.f); break; + case SURFACE_LAMP_POST: result = GetCollisionRatio(b, 1.f, 10.f, 9.f); break; + case SURFACE_FIRE_HYDRANT: result = GetCollisionRatio(b, 1.f, 15.f, 14.f); break; + case SURFACE_GIRDER: result = GetCollisionRatio(b, 8.f, 50.f, 42.f); break; + case SURFACE_METAL_CHAIN_FENCE: result = GetCollisionRatio(b, 0.1f, 10.f, 9.9f); break; + case SURFACE_PED: result = GetCollisionRatio(b, 0.f, 20.f, 20.f); break; case SURFACE_SAND: result = GetCollisionRatio(b, 0.f, 10.f, 10.f); break; - case SURFACE_PUDDLE: result = GetCollisionRatio(b, 0.f, 10.f, 10.f); break; - case SURFACE_WOOD: result = GetCollisionRatio(b, 1.f, 4.f, 3.f); break; - case SURFACE_WOOD_BOX: result = GetCollisionRatio(b, 0.1f, 5.f, 4.9f); break; - case SURFACE_WOOD_PLANK: result = GetCollisionRatio(b, 0.1f, 40.f, 39.9f); break; - case SURFACE_TIRE: - case SURFACE_RUBBER29: result = GetCollisionRatio(b, 0.f, 10.f, 10.f); break; - case SURFACE_HARD24: result = GetCollisionRatio(b, 0.1f, 4.f, 3.9f); break; + case SURFACE_WATER: result = GetCollisionRatio(b, 0.f, 10.f, 10.f); break; + case SURFACE_WOOD_CRATES: result = GetCollisionRatio(b, 1.f, 4.f, 3.f); break; + case SURFACE_WOOD_BENCH: result = GetCollisionRatio(b, 0.1f, 5.f, 4.9f); break; + case SURFACE_WOOD_SOLID: result = GetCollisionRatio(b, 0.1f, 40.f, 39.9f); break; + case SURFACE_RUBBER: + case SURFACE_WHEELBASE: result = GetCollisionRatio(b, 0.f, 10.f, 10.f); break; + case SURFACE_PLASTIC: result = GetCollisionRatio(b, 0.1f, 4.f, 3.9f); break; case SURFACE_HEDGE: result = GetCollisionRatio(b, 0.f, 0.5f, 0.5f); break; - case SURFACE_METAL27: result = GetCollisionRatio(b, 4.f, 40.f, 36.f); break; - case SURFACE_METAL28: result = GetCollisionRatio(b, 0.f, 5.f, 5.f); break; + case SURFACE_CONTAINER: result = GetCollisionRatio(b, 4.f, 40.f, 36.f); break; + case SURFACE_NEWS_VENDOR: result = GetCollisionRatio(b, 0.f, 5.f, 5.f); break; default: result = 0.f; break; } @@ -130,18 +130,18 @@ cAudioManager::SetLoopingCollisionRequestedSfxFreqAndGetVol(const cAudioCollisio m_sQueueSample.m_nSampleIndex = SFX_RAIN; m_sQueueSample.m_nFrequency = 13000.f * ratio + 35000; vol = 50.f * ratio; - } else if(surface1 == SURFACE_PUDDLE || surface2 == SURFACE_PUDDLE) { + } else if(surface1 == SURFACE_WATER || surface2 == SURFACE_WATER) { ratio = GetCollisionRatio(audioCollision.m_fIntensity2, 0.0001f, 0.09f, 0.0899f); m_sQueueSample.m_nSampleIndex = SFX_BOAT_WATER_LOOP; m_sQueueSample.m_nFrequency = 6050.f * ratio + 16000; vol = 30.f * ratio; - } else if(surface1 == SURFACE_DIRT || surface2 == SURFACE_DIRT || surface1 == SURFACE_DIRTTRACK || - surface2 == SURFACE_DIRTTRACK || surface1 == SURFACE_SAND || surface2 == SURFACE_SAND) { + } else if(surface1 == SURFACE_GRAVEL || surface2 == SURFACE_GRAVEL || surface1 == SURFACE_MUD_DRY || + surface2 == SURFACE_MUD_DRY || surface1 == SURFACE_SAND || surface2 == SURFACE_SAND) { ratio = GetCollisionRatio(audioCollision.m_fIntensity2, 0.0001f, 0.09f, 0.0899f); m_sQueueSample.m_nSampleIndex = SFX_GRAVEL_SKID; m_sQueueSample.m_nFrequency = 6000.f * ratio + 10000; vol = 50.f * ratio; - } else if(surface1 == SURFACE_FLESH || surface2 == SURFACE_FLESH) { + } else if(surface1 == SURFACE_PED || surface2 == SURFACE_PED) { return 0; } else { ratio = GetCollisionRatio(audioCollision.m_fIntensity2, 0.0001f, 0.09f, 0.0899f); @@ -240,9 +240,9 @@ cAudioManager::SetUpOneShotCollisionSound(const cAudioCollision &col) s2 = col.m_bSurface2; } ratio = GetCollisionOneShotRatio(s1, col.m_fIntensity1); - if(s1 == SURFACE_METAL6 && s2 == SURFACE_FLESH) ratio /= 4.0f; - if(s1 == SURFACE_METAL6 && ratio < 0.6f) { - s1 = SURFACE_BILLBOARD; + if(s1 == SURFACE_CAR && s2 == SURFACE_PED) ratio /= 4.0f; + if(s1 == SURFACE_CAR && ratio < 0.6f) { + s1 = SURFACE_CAR_PANEL; ratio = Min(1.f, 2.f * ratio); } emittingVol = 40.f * ratio; @@ -290,13 +290,13 @@ cAudioManager::SetUpOneShotCollisionSound(const cAudioCollision &col) } switch(s1) { case SURFACE_GLASS: m_sQueueSample.m_nFrequency = 13500; break; - case SURFACE_METAL15: m_sQueueSample.m_nFrequency = 8819; break; - case SURFACE_PUDDLE: + case SURFACE_GIRDER: m_sQueueSample.m_nFrequency = 8819; break; + case SURFACE_WATER: m_sQueueSample.m_nFrequency = 2 * SampleManager.GetSampleBaseFrequency(m_sQueueSample.m_nSampleIndex); break; - case SURFACE_TIRE: m_sQueueSample.m_nFrequency = 6000; break; - case SURFACE_HARD24: m_sQueueSample.m_nFrequency = 8000; break; + case SURFACE_RUBBER: m_sQueueSample.m_nFrequency = 6000; break; + case SURFACE_PLASTIC: m_sQueueSample.m_nFrequency = 8000; break; default: m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(m_sQueueSample.m_nSampleIndex); diff --git a/src/audio/AudioLogic.cpp b/src/audio/AudioLogic.cpp new file mode 100644 index 00000000..de71355e --- /dev/null +++ b/src/audio/AudioLogic.cpp @@ -0,0 +1,6435 @@ +#include "common.h" + +#include "AudioManager.h" +#include "audio_enums.h" + +#include "Automobile.h" +#include "Boat.h" +#include "Bridge.h" +#include "Camera.h" +#include "Cranes.h" +#include "DMAudio.h" +#include "Entity.h" +#include "Explosion.h" +#include "Fire.h" +#include "Garages.h" +#include "General.h" +#include "HandlingMgr.h" +#include "Heli.h" +#include "ModelIndices.h" +#include "MusicManager.h" +#include "Pad.h" +#include "Ped.h" +#include "Physical.h" +#include "Placeable.h" +#include "Plane.h" +#include "PlayerPed.h" +#include "Pools.h" +#include "Projectile.h" +#include "ProjectileInfo.h" +#include "Replay.h" +#include "Stats.h" +#include "SurfaceTable.h" +#include "Train.h" +#include "Transmission.h" +#include "Vehicle.h" +#include "WaterCannon.h" +#include "Weather.h" +#include "ZoneCull.h" +#include "sampman.h" + +const int channels = ARRAY_SIZE(cAudioManager::m_asActiveSamples); +const int policeChannel = channels + 1; +const int allChannels = channels + 2; + +uint32 gPornNextTime; +uint32 gSawMillNextTime; +uint32 gShopNextTime; +uint32 gAirportNextTime; +uint32 gCinemaNextTime; +uint32 gDocksNextTime; +uint32 gHomeNextTime; +uint32 gCellNextTime; +uint32 gNextCryTime; + +enum PLAY_STATUS : uint8 { PLAY_STATUS_STOPPED = 0, PLAY_STATUS_PLAYING, PLAY_STATUS_FINISHED }; +enum LOADING_STATUS : uint8 { LOADING_STATUS_NOT_LOADED = 0, LOADING_STATUS_LOADED, LOADING_STATUS_FAILED }; + +void +cAudioManager::PreInitialiseGameSpecificSetup() const +{ + BankStartOffset[SAMPLEBANK_MAIN] = SAMPLEBANK_START; + BankStartOffset[SAMPLEBANK_PED] = SAMPLEBANK_PED_START; +} + +void +cAudioManager::PostInitialiseGameSpecificSetup() +{ + m_nFireAudioEntity = CreateEntity(AUDIOTYPE_FIRE, &gFireManager); + if (m_nFireAudioEntity >= 0) + SetEntityStatus(m_nFireAudioEntity, 1); + + m_nCollisionEntity = CreateEntity(AUDIOTYPE_COLLISION, (void *)1); + if (m_nCollisionEntity >= 0) + SetEntityStatus(m_nCollisionEntity, 1); + + m_nFrontEndEntity = CreateEntity(AUDIOTYPE_FRONTEND, (void *)1); + if (m_nFrontEndEntity >= 0) + SetEntityStatus(m_nFrontEndEntity, 1); + + m_nProjectileEntity = CreateEntity(AUDIOTYPE_PROJECTILE, (void *)1); + if (m_nProjectileEntity >= 0) + SetEntityStatus(m_nProjectileEntity, 1); + + m_nWaterCannonEntity = CreateEntity(AUDIOTYPE_WATERCANNON, (void *)1); + if (m_nWaterCannonEntity >= 0) + SetEntityStatus(m_nWaterCannonEntity, 1); + + m_nPoliceChannelEntity = CreateEntity(AUDIOTYPE_POLICERADIO, (void *)1); + if (m_nPoliceChannelEntity >= 0) + SetEntityStatus(m_nPoliceChannelEntity, 1); + + m_nBridgeEntity = CreateEntity(AUDIOTYPE_BRIDGE, (void *)1); + if (m_nBridgeEntity >= 0) + SetEntityStatus(m_nBridgeEntity, 1); + + m_sMissionAudio.m_nSampleIndex = NO_SAMPLE; + m_sMissionAudio.m_nLoadingStatus = LOADING_STATUS_NOT_LOADED; + m_sMissionAudio.m_nPlayStatus = PLAY_STATUS_STOPPED; + m_sMissionAudio.field_22 = 0; + m_sMissionAudio.m_bIsPlayed = false; + m_sMissionAudio.m_bPredefinedProperties = true; + m_sMissionAudio.m_nMissionAudioCounter = 0; + ResetAudioLogicTimers(CTimer::GetTimeInMilliseconds()); +} +void +cAudioManager::PreTerminateGameSpecificShutdown() +{ + if (m_nBridgeEntity >= 0) { + DestroyEntity(m_nBridgeEntity); + m_nBridgeEntity = AEHANDLE_NONE; + } + if (m_nPoliceChannelEntity >= 0) { + DestroyEntity(m_nPoliceChannelEntity); + m_nPoliceChannelEntity = AEHANDLE_NONE; + } + if (m_nWaterCannonEntity >= 0) { + DestroyEntity(m_nWaterCannonEntity); + m_nWaterCannonEntity = AEHANDLE_NONE; + } + if (m_nFireAudioEntity >= 0) { + DestroyEntity(m_nFireAudioEntity); + m_nFireAudioEntity = AEHANDLE_NONE; + } + if (m_nCollisionEntity >= 0) { + DestroyEntity(m_nCollisionEntity); + m_nCollisionEntity = AEHANDLE_NONE; + } + if (m_nFrontEndEntity >= 0) { + DestroyEntity(m_nFrontEndEntity); + m_nFrontEndEntity = AEHANDLE_NONE; + } + if (m_nProjectileEntity >= 0) { + DestroyEntity(m_nProjectileEntity); + m_nProjectileEntity = AEHANDLE_NONE; + } +} + +void +cAudioManager::PostTerminateGameSpecificShutdown() +{ + ; +} + +void +cAudioManager::ResetAudioLogicTimers(uint32 timer) +{ + gPornNextTime = timer; + gNextCryTime = timer; + gSawMillNextTime = timer; + gCellNextTime = timer; + gShopNextTime = timer; + gHomeNextTime = timer; + gAirportNextTime = timer; + gDocksNextTime = timer; + gCinemaNextTime = timer; + for (int32 i = 0; i < m_nAudioEntitiesTotal; i++) { + if (m_asAudioEntities[m_anAudioEntityIndices[i]].m_nType == AUDIOTYPE_PHYSICAL) { + CPed *ped = (CPed *)m_asAudioEntities[m_anAudioEntityIndices[i]].m_pEntity; + if (ped->IsPed()) { + ped->m_lastSoundStart = timer; + ped->m_soundStart = timer + m_anRandomTable[0] % 3000; + } + } + } + ClearMissionAudio(); + SampleManager.StopChannel(policeChannel); +} + +void +cAudioManager::ProcessReverb() const +{ + if (SampleManager.UpdateReverb() && m_bDynamicAcousticModelingStatus) { + for (uint32 i = 0; i < +#ifdef FIX_BUGS + channels +#else + 28 +#endif + ; + i++) { + if (m_asActiveSamples[i].m_bReverbFlag) + SampleManager.SetChannelReverbFlag(i, 1); + } + } +} + +float +cAudioManager::GetDistanceSquared(const CVector &v) const +{ + const CVector &c = TheCamera.GetPosition(); + return sq(v.x - c.x) + sq(v.y - c.y) + sq((v.z - c.z) * 0.2f); +} + +void +cAudioManager::CalculateDistance(bool &distCalculated, float dist) +{ + if (!distCalculated) { + m_sQueueSample.m_fDistance = Sqrt(dist); + distCalculated = true; + } +} + +void +cAudioManager::ProcessSpecial() +{ + if (m_nUserPause) { + if (!m_nPreviousUserPause) { + MusicManager.ChangeMusicMode(MUSICMODE_FRONTEND); + SampleManager.SetEffectsFadeVolume(MAX_VOLUME); + SampleManager.SetMusicFadeVolume(MAX_VOLUME); + } + } else { + if (m_nPreviousUserPause) { + MusicManager.StopFrontEndTrack(); + MusicManager.ChangeMusicMode(MUSICMODE_GAME); + } + CPlayerPed *playerPed = FindPlayerPed(); + if (playerPed) { + const PedState &state = playerPed->m_nPedState; + if (state != PED_ENTER_CAR && state != PED_STEAL_CAR && !playerPed->bInVehicle) + SampleManager.StopChannel(m_nActiveSamples); + } + } +} + +void +cAudioManager::ProcessEntity(int32 id) +{ + if (m_asAudioEntities[id].m_nStatus) { + m_sQueueSample.m_nEntityIndex = id; + switch (m_asAudioEntities[id].m_nType) { + case AUDIOTYPE_PHYSICAL: + if (!m_nUserPause) { + m_sQueueSample.m_bReverbFlag = true; + ProcessPhysical(id); + } + break; + case AUDIOTYPE_EXPLOSION: + if (!m_nUserPause) { + m_sQueueSample.m_bReverbFlag = true; + ProcessExplosions(id); + } + break; + case AUDIOTYPE_FIRE: + if (!m_nUserPause) { + m_sQueueSample.m_bReverbFlag = true; + ProcessFires(id); + } + break; + case AUDIOTYPE_WEATHER: + if (!m_nUserPause) { + m_sQueueSample.m_bReverbFlag = true; + ProcessWeather(id); + } + break; + case AUDIOTYPE_CRANE: + if (!m_nUserPause) { + m_sQueueSample.m_bReverbFlag = true; + ProcessCrane(); + } + break; + case AUDIOTYPE_SCRIPTOBJECT: + if (!m_nUserPause) { + m_sQueueSample.m_bReverbFlag = true; + ProcessScriptObject(id); + } + break; + case AUDIOTYPE_BRIDGE: + if (!m_nUserPause) { + m_sQueueSample.m_bReverbFlag = true; + ProcessBridge(); + } + break; + case AUDIOTYPE_FRONTEND: + m_sQueueSample.m_bReverbFlag = false; + ProcessFrontEnd(); + break; + case AUDIOTYPE_PROJECTILE: + if (!m_nUserPause) { + m_sQueueSample.m_bReverbFlag = true; + ProcessProjectiles(); + } + break; + case AUDIOTYPE_GARAGE: + if (!m_nUserPause) + ProcessGarages(); + break; + case AUDIOTYPE_FIREHYDRANT: + if (!m_nUserPause) { + m_sQueueSample.m_bReverbFlag = true; + ProcessFireHydrant(); + } + break; + case AUDIOTYPE_WATERCANNON: + if (!m_nUserPause) { + m_sQueueSample.m_bReverbFlag = true; + ProcessWaterCannon(id); + } + break; + default: + return; + } + } +} + +void +cAudioManager::ProcessPhysical(int32 id) +{ + CPhysical *entity = (CPhysical *)m_asAudioEntities[id].m_pEntity; + if (entity) { + switch (entity->GetType()) { + case ENTITY_TYPE_VEHICLE: + ProcessVehicle((CVehicle *)m_asAudioEntities[id].m_pEntity); + break; + case ENTITY_TYPE_PED: + ProcessPed((CPhysical *)m_asAudioEntities[id].m_pEntity); + break; + default: + return; + } + } +} + +#pragma region VEHICLE AUDIO +enum eVehicleModel { + LANDSTAL, + IDAHO, + STINGER, + LINERUN, + PEREN, + SENTINEL, + RIO, + FIRETRUK, + TRASH, + STRETCH, + MANANA, + INFERNUS, + VOODOO, + PONY, + MULE, + CHEETAH, + AMBULAN, + FBICAR, + MOONBEAM, + ESPERANT, + TAXI, + WASHING, + BOBCAT, + MRWHOOP, + BFINJECT, + HUNTER, + POLICE, + ENFORCER, + SECURICA, + BANSHEE, + PREDATOR, + BUS, + RHINO, + BARRACKS, + CUBAN, + CHOPPER, + ANGEL, + COACH, + CABBIE, + STALLION, + RUMPO, + RCBANDIT, + ROMERO, + PACKER, + SENTXS, + ADMIRAL, + SQUALO, + SEASPAR, + PIZZABOY, + GANGBUR, + AIRTRAIN, + DEADDODO, + SPEEDER, + REEFER, + TROPIC, + FLATBED, + YANKEE, + CADDY, + ZEBRA, + TOPFUN, + SKIMMER, + PCJ600, + FAGGIO, + FREEWAY, + RCBARON, + RCRAIDER, + GLENDALE, + OCEANIC, + SANCHEZ, + SPARROW, + PATRIOT, + LOVEFIST, + COASTG, + DINGHY, + HERMES, + SABRE, + SABRETUR, + PHEONIX, + WALTON, + REGINA, + COMET, + DELUXO, + BURRITO, + SPAND, + MARQUIS, + BAGGAGE, + KAUFMAN, + MAVERICK, + VCNMAV, + RANCHER, + FBIRANCH, + VIRGO, + GREENWOO, + JETMAX, + HOTRING, + SANDKING, + BLISTAC, + POLMAV, + BOXVILLE, + BENSON, + MESA, + RCGOBLIN, + HOTRINA, + HOTRINB, + BLOODRA, + BLOODRB, + VICECHEE, + + // HACK so this compiles + // TODO(MIAMI): check it out + DODO = -1 +}; + +enum +{ + DOOR_TYPE_OLD = 0, + DOOR_TYPE_NEW, + DOOR_TYPE_TRUCK, + DOOR_TYPE_AIRBREAK, +}; + + +struct tVehicleSampleData { + eSfxSample m_nAccelerationSampleIndex; + uint8 m_bEngineSoundType; + eSfxSample m_nHornSample; + int32 m_nHornFrequency; + uint8 m_nSirenOrAlarmSample; + int32 m_nSirenOrAlarmFrequency; + uint8 m_bDoorType; +}; + +const tVehicleSampleData aVehicleSettings[110] = { {SFX_CAR_REV_2, 2, SFX_CAR_HORN_JEEP, 26513, SFX_CAR_HORN_JEEP, 9935, 1}, + {SFX_CAR_REV_1, 1, SFX_CAR_HORN_56CHEV, 11487, SFX_CAR_HORN_JEEP, 9935, 0}, + {SFX_CAR_REV_8, 8, SFX_CAR_HORN_PORSCHE, 11025, SFX_CAR_HORN_JEEP, 10928, 1}, + {SFX_CAR_REV_6, 6, SFX_CAR_HORN_TRUCK, 29711, SFX_CAR_HORN_JEEP, 9935, 2}, + {SFX_CAR_REV_1, 1, SFX_CAR_HORN_56CHEV, 12893, SFX_CAR_HORN_JEEP, 8941, 0}, + {SFX_CAR_REV_5, 5, SFX_CAR_HORN_BMW328, 10706, SFX_CAR_HORN_JEEP, 11922, 1}, + {SFX_CAR_REV_4, 4, SFX_CAR_HORN_TRUCK, 29711, SFX_CAR_HORN_JEEP, 7948, 2}, + {SFX_CAR_REV_6, 6, SFX_CAR_HORN_TRUCK, 29711, SFX_POLICE_SIREN_SLOW, 11556, 2}, + {SFX_CAR_REV_6, 6, SFX_CAR_HORN_TRUCK, 31478, SFX_CAR_HORN_JEEP, 8941, 2}, + {SFX_CAR_REV_1, 1, SFX_CAR_HORN_BMW328, 9538, SFX_CAR_HORN_JEEP, 12220, 1}, + {SFX_CAR_REV_1, 1, SFX_CAR_HORN_56CHEV, 10842, SFX_CAR_HORN_JEEP, 9935, 0}, + {SFX_CAR_REV_3, 3, SFX_CAR_HORN_BMW328, 12017, SFX_CAR_HORN_JEEP, 9935, 1}, + {SFX_CAR_REV_2, 2, SFX_CAR_HORN_JEEP, 22295, SFX_CAR_HORN_JEEP, 12200, 1}, + {SFX_CAR_REV_4, 4, SFX_CAR_HORN_BUS2, 18000, SFX_CAR_HORN_JEEP, 13400, 1}, + {SFX_CAR_REV_4, 4, SFX_CAR_HORN_BUS, 18286, SFX_CAR_HORN_JEEP, 9935, 2}, + {SFX_CAR_REV_3, 3, SFX_CAR_HORN_PORSCHE, 11025, SFX_CAR_HORN_JEEP, 13600, 1}, + {SFX_CAR_REV_4, 4, SFX_CAR_HORN_JEEP, 22295, SFX_AMBULANCE_SIREN_SLOW, 8795, 2}, + {SFX_CAR_REV_5, 5, SFX_CAR_HORN_PORSCHE, 9271, SFX_POLICE_SIREN_SLOW, 16168, 1}, + {SFX_CAR_REV_1, 1, SFX_CAR_HORN_56CHEV, 12170, SFX_CAR_HORN_JEEP, 8000, 1}, + {SFX_CAR_REV_1, 1, SFX_CAR_HORN_BUS2, 12345, SFX_CAR_HORN_JEEP, 9935, 0}, + {SFX_CAR_REV_2, 2, SFX_CAR_HORN_BMW328, 10796, SFX_CAR_HORN_JEEP, 8543, 1}, + {SFX_CAR_REV_5, 5, SFX_CAR_HORN_PORSCHE, 9271, SFX_CAR_HORN_JEEP, 9935, 1}, + {SFX_CAR_REV_2, 2, SFX_CAR_HORN_PICKUP, 10924, SFX_CAR_HORN_JEEP, 9935, 1}, + {SFX_CAR_REV_1, 1, SFX_CAR_HORN_PICKUP, 11025, SFX_ICE_CREAM_TUNE, 11025, 0}, + {SFX_CAR_REV_7, 7, SFX_CAR_HORN_JEEP, 26513, SFX_CAR_HORN_JEEP, 9935, 1}, + {SFX_CAR_REV_1, 1, SFX_CAR_HORN_JEEP, 26513, SFX_CAR_HORN_JEEP, 10000, 0}, + {SFX_CAR_REV_5, 5, SFX_CAR_HORN_BMW328, 10706, SFX_POLICE_SIREN_SLOW, 13596, 1}, + {SFX_CAR_REV_4, 4, SFX_CAR_HORN_BUS, 17260, SFX_POLICE_SIREN_SLOW, 13000, 2}, + {SFX_CAR_REV_4, 4, SFX_CAR_HORN_PICKUP, 8670, SFX_CAR_HORN_JEEP, 9935, 2}, + {SFX_CAR_REV_8, 8, SFX_CAR_HORN_PORSCHE, 10400, SFX_CAR_HORN_JEEP, 10123, 1}, + {SFX_CAR_REV_1, 1, SFX_CAR_HORN_JEEP, 26513, SFX_POLICE_SIREN_SLOW, 13596, 0}, + {SFX_CAR_REV_6, 6, SFX_CAR_HORN_BUS2, 11652, SFX_CAR_HORN_JEEP, 10554, 3}, + {SFX_CAR_REV_6, 6, SFX_CAR_HORN_TRUCK, 29711, SFX_CAR_HORN_JEEP, 8000, 2}, + {SFX_CAR_REV_6, 6, SFX_CAR_HORN_TRUCK, 28043, SFX_CAR_HORN_JEEP, 9935, 2}, + {SFX_CAR_REV_1, 0, SFX_CAR_HORN_TRUCK, 29711, SFX_CAR_HORN_JEEP, 9935, 3}, + {SFX_CAR_REV_1, 0, SFX_CAR_HORN_JEEP, 26513, SFX_CAR_HORN_JEEP, 9935, 0}, + {SFX_CESNA_IDLE, 0, SFX_CAR_HORN_JEEP, 26513, SFX_CAR_HORN_JEEP, 9935, 0}, + {SFX_CAR_REV_6, 6, SFX_CAR_HORN_BUS, 16291, SFX_CAR_HORN_JEEP, 7500, 3}, + {SFX_CAR_REV_1, 1, SFX_CAR_HORN_56CHEV, 10842, SFX_CAR_HORN_JEEP, 9935, 0}, + {SFX_CAR_REV_1, 1, SFX_CAR_HORN_56CHEV, 10233, SFX_CAR_HORN_JEEP, 8935, 0}, + {SFX_CAR_REV_4, 4, SFX_CAR_HORN_PICKUP, 8670, SFX_CAR_HORN_JEEP, 8935, 0}, + {SFX_CAR_REV_1, 0, SFX_CAR_HORN_PICKUP, 2000, SFX_CAR_HORN_JEEP, 17000, 0}, + {SFX_CAR_REV_4, 4, SFX_CAR_HORN_JEEP, 21043, SFX_CAR_HORN_JEEP, 9935, 0}, + {SFX_CAR_REV_4, 4, SFX_CAR_HORN_JEEP, 21043, SFX_CAR_HORN_JEEP, 9935, 0}, + {SFX_CAR_REV_5, 5, SFX_CAR_HORN_BMW328, 9003, SFX_CAR_HORN_JEEP, 9935, 1}, + {SFX_CAR_REV_2, 2, SFX_CAR_HORN_PORSCHE, 12375, SFX_CAR_HORN_JEEP, 9935, 1}, + {SFX_CAR_REV_5, 5, SFX_CAR_HORN_BUS2, 15554, SFX_CAR_HORN_JEEP, 9935, 1}, + {SFX_CAR_REV_7, 7, SFX_CAR_HORN_BUS2, 13857, SFX_CAR_HORN_JEEP, 9935, 0}, + {SFX_CAR_REV_7, 7, SFX_CAR_HORN_PICKUP, 10924, SFX_CAR_HORN_JEEP, 9935, 0}, + {SFX_CAR_REV_4, 4, SFX_CAR_HORN_JEEP, 21043, SFX_CAR_HORN_JEEP, 9935, 2}, + {SFX_CAR_REV_1, 0, SFX_CAR_HORN_JEEP, 20143, SFX_CAR_HORN_JEEP, 9935, 0}, + {SFX_CAR_REV_1, 0, SFX_CAR_HORN_JEEP, 21043, SFX_CAR_HORN_JEEP, 9935, 0}, + {SFX_CAR_REV_1, 1, SFX_CAR_HORN_JEEP, 21043, SFX_CAR_HORN_JEEP, 9935, 0}, + {SFX_CAR_REV_1, 1, SFX_CAR_HORN_JEEP, 21043, SFX_CAR_HORN_JEEP, 9935, 0}, + {SFX_CAR_REV_4, 4, SFX_CAR_HORN_JEEP, 21043, SFX_CAR_HORN_JEEP, 9000, 0}, + {SFX_CAR_REV_6, 6, SFX_CAR_HORN_TRUCK, 28043, SFX_CAR_HORN_JEEP, 9935, 2}, + {SFX_CAR_REV_4, 4, SFX_CAR_HORN_BUS, 18286, SFX_CAR_HORN_JEEP, 9935, 2}, + {SFX_CAR_REV_1, 1, SFX_CAR_HORN_JEEP, 21043, SFX_CAR_HORN_JEEP, 9935, 0}, + {SFX_CAR_REV_1, 1, SFX_CAR_HORN_56CHEV, 10842, SFX_CAR_HORN_JEEP, 9935, 0}, + {SFX_CAR_REV_4, 4, SFX_CAR_HORN_BUS2, 18000, SFX_CAR_HORN_JEEP, 13400, 1}, + {SFX_CAR_REV_1, 1, SFX_CAR_HORN_JEEP, 21043, SFX_CAR_HORN_JEEP, 9935, 0}, + {SFX_CAR_REV_1, 1, SFX_CAR_HORN_JEEP, 21043, SFX_CAR_HORN_JEEP, 9935, 0}, + {SFX_CAR_REV_1, 1, SFX_CAR_HORN_JEEP, 21043, SFX_CAR_HORN_JEEP, 9935, 0}, + {SFX_CAR_REV_1, 1, SFX_CAR_HORN_JEEP, 21043, SFX_CAR_HORN_JEEP, 9935, 0}, + {SFX_CAR_REV_1, 1, SFX_CAR_HORN_JEEP, 21043, SFX_CAR_HORN_JEEP, 9935, 0}, + {SFX_CAR_REV_1, 1, SFX_CAR_HORN_JEEP, 21043, SFX_CAR_HORN_JEEP, 9935, 0}, + {SFX_CAR_REV_1, 1, SFX_CAR_HORN_JEEP, 21043, SFX_CAR_HORN_JEEP, 9935, 0}, + {SFX_CAR_REV_1, 1, SFX_CAR_HORN_JEEP, 21043, SFX_CAR_HORN_JEEP, 9935, 0}, + {SFX_CAR_REV_1, 1, SFX_CAR_HORN_JEEP, 21043, SFX_CAR_HORN_JEEP, 9935, 0}, + {SFX_CAR_REV_1, 1, SFX_CAR_HORN_JEEP, 21043, SFX_CAR_HORN_JEEP, 9935, 0}, + {SFX_CAR_REV_1, 1, SFX_CAR_HORN_JEEP, 21043, SFX_CAR_HORN_JEEP, 9935, 0}, + {SFX_CAR_REV_1, 1, SFX_CAR_HORN_JEEP, 21043, SFX_CAR_HORN_JEEP, 9935, 0}, + {SFX_CAR_REV_1, 1, SFX_CAR_HORN_JEEP, 21043, SFX_CAR_HORN_JEEP, 9935, 0}, + {SFX_CAR_REV_1, 1, SFX_CAR_HORN_JEEP, 21043, SFX_CAR_HORN_JEEP, 9935, 0}, + {SFX_CAR_REV_1, 1, SFX_CAR_HORN_JEEP, 21043, SFX_CAR_HORN_JEEP, 9935, 0}, + {SFX_CAR_REV_1, 1, SFX_CAR_HORN_JEEP, 21043, SFX_CAR_HORN_JEEP, 9935, 0}, + {SFX_CAR_REV_1, 1, SFX_CAR_HORN_JEEP, 21043, SFX_CAR_HORN_JEEP, 9935, 0}, + {SFX_CAR_REV_1, 1, SFX_CAR_HORN_JEEP, 21043, SFX_CAR_HORN_JEEP, 9935, 0}, + {SFX_CAR_REV_1, 1, SFX_CAR_HORN_JEEP, 21043, SFX_CAR_HORN_JEEP, 9935, 0}, + {SFX_CAR_REV_1, 1, SFX_CAR_HORN_JEEP, 21043, SFX_CAR_HORN_JEEP, 9935, 0}, + {SFX_CAR_REV_1, 1, SFX_CAR_HORN_JEEP, 21043, SFX_CAR_HORN_JEEP, 9935, 0}, + {SFX_CAR_REV_1, 1, SFX_CAR_HORN_JEEP, 21043, SFX_CAR_HORN_JEEP, 9935, 0}, + {SFX_CAR_REV_1, 1, SFX_CAR_HORN_JEEP, 21043, SFX_CAR_HORN_JEEP, 9935, 0}, + {SFX_CAR_REV_1, 1, SFX_CAR_HORN_JEEP, 21043, SFX_CAR_HORN_JEEP, 9935, 0}, + {SFX_CAR_REV_1, 1, SFX_CAR_HORN_JEEP, 21043, SFX_CAR_HORN_JEEP, 9935, 0}, + {SFX_CAR_REV_1, 1, SFX_CAR_HORN_JEEP, 21043, SFX_CAR_HORN_JEEP, 9935, 0}, + {SFX_CAR_REV_1, 1, SFX_CAR_HORN_JEEP, 21043, SFX_CAR_HORN_JEEP, 9935, 0}, + {SFX_CAR_REV_1, 1, SFX_CAR_HORN_JEEP, 21043, SFX_CAR_HORN_JEEP, 9935, 0}, + {SFX_CAR_REV_1, 1, SFX_CAR_HORN_JEEP, 21043, SFX_CAR_HORN_JEEP, 9935, 0}, + {SFX_CAR_REV_1, 1, SFX_CAR_HORN_JEEP, 21043, SFX_CAR_HORN_JEEP, 9935, 0}, + {SFX_CAR_REV_1, 1, SFX_CAR_HORN_JEEP, 21043, SFX_CAR_HORN_JEEP, 9935, 0}, + {SFX_CAR_REV_1, 1, SFX_CAR_HORN_JEEP, 21043, SFX_CAR_HORN_JEEP, 9935, 0}, + {SFX_CAR_REV_1, 1, SFX_CAR_HORN_JEEP, 21043, SFX_CAR_HORN_JEEP, 9935, 0}, + {SFX_CAR_REV_1, 1, SFX_CAR_HORN_JEEP, 21043, SFX_CAR_HORN_JEEP, 9935, 0}, + {SFX_CAR_REV_1, 1, SFX_CAR_HORN_JEEP, 21043, SFX_CAR_HORN_JEEP, 9935, 0}, + {SFX_CAR_REV_1, 1, SFX_CAR_HORN_JEEP, 21043, SFX_CAR_HORN_JEEP, 9935, 0}, + {SFX_CAR_REV_1, 1, SFX_CAR_HORN_JEEP, 21043, SFX_CAR_HORN_JEEP, 9935, 0}, + {SFX_CAR_REV_1, 1, SFX_CAR_HORN_JEEP, 21043, SFX_CAR_HORN_JEEP, 9935, 0}, + {SFX_CAR_REV_1, 1, SFX_CAR_HORN_JEEP, 21043, SFX_CAR_HORN_JEEP, 9935, 0}, + {SFX_CAR_REV_1, 1, SFX_CAR_HORN_JEEP, 21043, SFX_CAR_HORN_JEEP, 9935, 0}, + {SFX_CAR_REV_1, 1, SFX_CAR_HORN_JEEP, 21043, SFX_CAR_HORN_JEEP, 9935, 0}, + {SFX_CAR_REV_1, 1, SFX_CAR_HORN_JEEP, 21043, SFX_CAR_HORN_JEEP, 9935, 0}, + {SFX_CAR_REV_1, 1, SFX_CAR_HORN_JEEP, 21043, SFX_CAR_HORN_JEEP, 9935, 0}, + {SFX_CAR_REV_1, 1, SFX_CAR_HORN_JEEP, 21043, SFX_CAR_HORN_JEEP, 9935, 0}, + {SFX_CAR_REV_1, 1, SFX_CAR_HORN_JEEP, 21043, SFX_CAR_HORN_JEEP, 9935, 0}, + {SFX_CAR_REV_1, 1, SFX_CAR_HORN_JEEP, 21043, SFX_CAR_HORN_JEEP, 9935, 0}, + {SFX_CAR_REV_1, 1, SFX_CAR_HORN_JEEP, 21043, SFX_CAR_HORN_JEEP, 9935, 0}, + {SFX_CAR_REV_1, 1, SFX_CAR_HORN_JEEP, 21043, SFX_CAR_HORN_JEEP, 9935, 0}, + {SFX_CAR_REV_1, 1, SFX_CAR_HORN_JEEP, 21043, SFX_CAR_HORN_JEEP, 9935, 0}, + {SFX_CAR_REV_1, 1, SFX_CAR_HORN_JEEP, 21043, SFX_CAR_HORN_JEEP, 9935, 0} }; + + +bool bPlayerJustEnteredCar; + +const bool hornPatternsArray[8][44] = { + {false, false, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, false, false, false, false, false, + false, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, false, false, false, false}, + {false, false, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, + true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, false, false}, + {false, false, true, true, true, true, true, true, true, true, true, true, false, false, false, false, true, true, true, true, true, false, + false, false, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, false}, + {false, false, true, true, true, true, true, false, false, true, true, true, true, true, false, false, false, true, true, true, true, true, + true, true, true, true, true, false, false, false, true, true, true, true, true, true, true, true, true, true, true, true, true, false}, + {false, false, true, true, true, true, true, true, true, true, true, false, false, false, false, false, false, false, false, false, false, false, + false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false}, + {false, false, true, true, true, false, false, false, true, true, true, false, false, false, false, false, false, false, false, false, false, false, + false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false}, + {false, false, true, true, true, true, false, false, false, false, true, true, true, false, false, true, true, true, false, false, true, true, + true, true, true, true, false, false, false, false, false, true, true, true, true, true, true, true, true, true, true, true, false, false}, + {false, false, true, true, true, true, false, false, true, true, true, true, true, false, false, false, true, true, true, true, true, true, + false, false, false, false, true, true, true, true, true, true, true, true, true, true, true, true, true, false, false, false, false, false}, +}; + + +void +cAudioManager::ProcessVehicle(CVehicle *veh) +{ + tHandlingData *handling = veh->pHandling; + float velChange; + cVehicleParams params; + m_sQueueSample.m_vecPos = veh->GetPosition(); + + params.m_bDistanceCalculated = false; + params.m_fDistance = GetDistanceSquared(m_sQueueSample.m_vecPos); + params.m_pVehicle = veh; + params.m_pTransmission = nil; + params.m_nIndex = 0; + params.m_fVelocityChange = 0.0f; + + if (handling != nil) + params.m_pTransmission = &handling->Transmission; + + params.m_nIndex = veh->GetModelIndex() - MI_FIRST_VEHICLE; + if (params.m_pVehicle->GetStatus() == STATUS_SIMPLE) + velChange = params.m_pVehicle->AutoPilot.m_fMaxTrafficSpeed * 0.02f; + else + velChange = DotProduct(params.m_pVehicle->m_vecMoveSpeed, params.m_pVehicle->GetForward()); + params.m_fVelocityChange = velChange; + switch (params.m_pVehicle->m_vehType) { + case VEHICLE_TYPE_CAR: + UpdateGasPedalAudio((CAutomobile *)veh); + if (params.m_nIndex == RCBANDIT) { + ProcessModelCarEngine(¶ms); + ProcessVehicleOneShots(¶ms); + ((CAutomobile *)veh)->m_fVelocityChangeForAudio = params.m_fVelocityChange; + break; + } + if (params.m_nIndex == DODO) { + if (!ProcessVehicleRoadNoise(¶ms)) { + ProcessVehicleOneShots(¶ms); + ((CAutomobile *)veh)->m_fVelocityChangeForAudio = params.m_fVelocityChange; + break; + } + if (CWeather::WetRoads > 0.f) + ProcessWetRoadNoise(¶ms); + ProcessVehicleSkidding(¶ms); + } else { + if (!ProcessVehicleRoadNoise(¶ms)) { + ProcessVehicleOneShots(¶ms); + ((CAutomobile *)veh)->m_fVelocityChangeForAudio = params.m_fVelocityChange; + break; + } + ProcessReverseGear(¶ms); + if (CWeather::WetRoads > 0.f) + ProcessWetRoadNoise(¶ms); + ProcessVehicleSkidding(¶ms); + ProcessVehicleHorn(¶ms); + ProcessVehicleSirenOrAlarm(¶ms); + if (UsesReverseWarning(params.m_nIndex)) + ProcessVehicleReverseWarning(¶ms); + if (HasAirBrakes(params.m_nIndex)) + ProcessAirBrakes(¶ms); + } + ProcessCarBombTick(¶ms); + ProcessVehicleEngine(¶ms); + ProcessEngineDamage(¶ms); + ProcessVehicleDoors(¶ms); + + ProcessVehicleOneShots(¶ms); + ((CAutomobile *)veh)->m_fVelocityChangeForAudio = params.m_fVelocityChange; + break; + case VEHICLE_TYPE_BOAT: + ProcessBoatEngine(¶ms); + ProcessBoatMovingOverWater(¶ms); + ProcessVehicleOneShots(¶ms); + break; + case VEHICLE_TYPE_TRAIN: + ProcessTrainNoise(¶ms); + ProcessVehicleOneShots(¶ms); + break; + case VEHICLE_TYPE_HELI: + ProcessHelicopter(¶ms); + ProcessVehicleOneShots(¶ms); + break; + case VEHICLE_TYPE_PLANE: + ProcessPlane(¶ms); + ProcessVehicleOneShots(¶ms); + break; + default: + break; + } + ProcessRainOnVehicle(¶ms); +} + +void +cAudioManager::ProcessRainOnVehicle(cVehicleParams *params) +{ + const int rainOnVehicleIntensity = 22; + if (params->m_fDistance < SQR(rainOnVehicleIntensity) && CWeather::Rain > 0.01f && (!CCullZones::CamNoRain() || !CCullZones::PlayerNoRain())) { + CVehicle *veh = params->m_pVehicle; + ++veh->m_bRainAudioCounter; + if (veh->m_bRainAudioCounter >= 2) { + veh->m_bRainAudioCounter = 0; + CalculateDistance(params->m_bDistanceCalculated, params->m_fDistance); + float emittingVol = 30.f * CWeather::Rain; + m_sQueueSample.m_nVolume = ComputeVolume(emittingVol, rainOnVehicleIntensity, m_sQueueSample.m_fDistance); + if (m_sQueueSample.m_nVolume != 0) { + m_sQueueSample.m_nCounter = veh->m_bRainSamplesCounter++; + if (veh->m_bRainSamplesCounter > 4) + veh->m_bRainSamplesCounter = 68; + m_sQueueSample.m_nSampleIndex = (m_anRandomTable[1] & 3) + SFX_CAR_RAIN_1; + m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_nReleasingVolumeModificator = 9; + m_sQueueSample.m_nFrequency = m_anRandomTable[1] % 4000 + 28000; + m_sQueueSample.m_nLoopCount = 1; + m_sQueueSample.m_nEmittingVolume = (uint8)emittingVol; + m_sQueueSample.m_nLoopStart = 0; + m_sQueueSample.m_nLoopEnd = -1; + m_sQueueSample.m_fSpeedMultiplier = 0.0f; + m_sQueueSample.m_fSoundIntensity = rainOnVehicleIntensity; + m_sQueueSample.m_bReleasingSoundFlag = true; + m_sQueueSample.m_bReverbFlag = false; + m_sQueueSample.m_bRequireReflection = false; + AddSampleToRequestedQueue(); + } + } + } +} + +bool +cAudioManager::ProcessReverseGear(cVehicleParams *params) +{ + const int reverseGearIntensity = 30; + + CVehicle *veh; + CAutomobile *automobile; + int32 emittingVol; + float modificator; + + if (params->m_fDistance >= SQR(reverseGearIntensity)) + return false; + veh = params->m_pVehicle; + if (veh->bEngineOn && (veh->m_fGasPedal < 0.0f || veh->m_nCurrentGear == 0)) { + CalculateDistance(params->m_bDistanceCalculated, params->m_fDistance); + automobile = (CAutomobile *)params->m_pVehicle; + if (automobile->m_nWheelsOnGround != 0) { + modificator = params->m_fVelocityChange / params->m_pTransmission->fMaxReverseVelocity; + } else { + if (automobile->m_nDriveWheelsOnGround != 0) + automobile->m_fGasPedalAudio *= 0.4f; + modificator = automobile->m_fGasPedalAudio; + } + modificator = Abs(modificator); + emittingVol = (24.f * modificator); + m_sQueueSample.m_nVolume = ComputeVolume(emittingVol, reverseGearIntensity, m_sQueueSample.m_fDistance); + if (m_sQueueSample.m_nVolume != 0) { + if (params->m_pVehicle->m_fGasPedal >= 0.0f) { + m_sQueueSample.m_nCounter = 62; + m_sQueueSample.m_nSampleIndex = SFX_REVERSE_GEAR_2; + } else { + m_sQueueSample.m_nCounter = 61; + m_sQueueSample.m_nSampleIndex = SFX_REVERSE_GEAR; + } + m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_nReleasingVolumeModificator = 3; + m_sQueueSample.m_nFrequency = (6000.f * modificator) + 7000; + m_sQueueSample.m_nLoopCount = 0; + m_sQueueSample.m_nEmittingVolume = emittingVol; + m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_fSpeedMultiplier = 3.0f; + m_sQueueSample.m_fSoundIntensity = reverseGearIntensity; + m_sQueueSample.m_bReleasingSoundFlag = false; + m_sQueueSample.m_nReleasingVolumeDivider = 5; + m_sQueueSample.m_bReverbFlag = true; + m_sQueueSample.m_bRequireReflection = false; + AddSampleToRequestedQueue(); + } + } + return true; +} + +void +cAudioManager::ProcessModelCarEngine(cVehicleParams *params) +{ + const float SOUND_INTENSITY = 30.0f; + CAutomobile *automobile; + float allowedVelocity; + int32 emittingVol; + float velocityChange; + + if (params->m_fDistance < SQR(SOUND_INTENSITY)) { + automobile = (CAutomobile *)params->m_pVehicle; + if (automobile->bEngineOn) { + if (automobile->m_nWheelsOnGround == 0) { + if (automobile->m_nDriveWheelsOnGround != 0) + automobile->m_fGasPedalAudio *= 0.4f; + velocityChange = automobile->m_fGasPedalAudio * params->m_pTransmission->fMaxVelocity; + } else { + velocityChange = Abs(params->m_fVelocityChange); + } + if (velocityChange > 0.001f) { + allowedVelocity = 0.5f * params->m_pTransmission->fMaxVelocity; + if (velocityChange < allowedVelocity) + emittingVol = (90.f * velocityChange / allowedVelocity); + else + emittingVol = 90; + if (emittingVol) { + CalculateDistance(params->m_bDistanceCalculated, params->m_fDistance); + m_sQueueSample.m_nVolume = ComputeVolume(emittingVol, 30.f, m_sQueueSample.m_fDistance); + if (m_sQueueSample.m_nVolume != 0) { + m_sQueueSample.m_nCounter = 2; + m_sQueueSample.m_nSampleIndex = SFX_REMOTE_CONTROLLED_CAR; + m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_nReleasingVolumeModificator = 1; + m_sQueueSample.m_nFrequency = (11025.f * velocityChange / params->m_pTransmission->fMaxVelocity + 11025.f); + m_sQueueSample.m_nLoopCount = 0; + m_sQueueSample.m_nEmittingVolume = emittingVol; + m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_fSpeedMultiplier = 3.0f; + m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY; + m_sQueueSample.m_bReleasingSoundFlag = false; + m_sQueueSample.m_nReleasingVolumeDivider = 3; + m_sQueueSample.m_bReverbFlag = true; + m_sQueueSample.m_bRequireReflection = false; + AddSampleToRequestedQueue(); + } + } + } + } + } +} + + + +bool +cAudioManager::ProcessVehicleRoadNoise(cVehicleParams *params) +{ + const float SOUND_INTENSITY = 95.0f; + + int32 emittingVol; + uint32 freq; + float modificator; + int sampleFreq; + float velocity; + + if (params->m_fDistance >= SQR(SOUND_INTENSITY)) + return false; + if (params->m_pTransmission != nil) { + if (((CAutomobile*)params->m_pVehicle)->m_nDriveWheelsOnGround != 0) { + velocity = Abs(params->m_fVelocityChange); + if (velocity > 0.0f) { + CalculateDistance(params->m_bDistanceCalculated, params->m_fDistance); + emittingVol = 30.f * Min(1.f, velocity / (0.5f * params->m_pTransmission->fMaxVelocity)); + m_sQueueSample.m_nVolume = ComputeVolume(emittingVol, SOUND_INTENSITY, m_sQueueSample.m_fDistance); + if (m_sQueueSample.m_nVolume != 0) { + m_sQueueSample.m_nCounter = 0; + m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_nReleasingVolumeModificator = 3; + if (params->m_pVehicle->m_nSurfaceTouched == SURFACE_WATER) { + m_sQueueSample.m_nSampleIndex = SFX_BOAT_WATER_LOOP; + freq = 6050 * emittingVol / 30 + 16000; + } else { + m_sQueueSample.m_nSampleIndex = SFX_ROAD_NOISE; + modificator = m_sQueueSample.m_fDistance / 190.f; + sampleFreq = SampleManager.GetSampleBaseFrequency(SFX_ROAD_NOISE); + freq = (sampleFreq * modificator) + ((3 * sampleFreq) / 4); + } + m_sQueueSample.m_nFrequency = freq; + m_sQueueSample.m_nLoopCount = 0; + m_sQueueSample.m_nEmittingVolume = emittingVol; + m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_fSpeedMultiplier = 6.0f; + m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY; + m_sQueueSample.m_bReleasingSoundFlag = false; + m_sQueueSample.m_nReleasingVolumeDivider = 4; + m_sQueueSample.m_bReverbFlag = true; + m_sQueueSample.m_bRequireReflection = false; + AddSampleToRequestedQueue(); + } + } + } + } + return true; +} + +bool +cAudioManager::ProcessWetRoadNoise(cVehicleParams *params) +{ + const float SOUND_INTENSITY = 30.0f; + + float relativeVelocity; + int32 emittingVol; + float modificator; + int freq; + float velChange; + + if (params->m_fDistance >= SQR(SOUND_INTENSITY)) + return false; + if (params->m_pTransmission != nil) { + if (((CAutomobile *)params->m_pVehicle)->m_nDriveWheelsOnGround != 0) { + velChange = Abs(params->m_fVelocityChange); + if (velChange > 0.f) { + CalculateDistance(params->m_bDistanceCalculated, params->m_fDistance); + relativeVelocity = Min(1.0f, velChange / (0.5f * params->m_pTransmission->fMaxVelocity)); + emittingVol = 23.0f * relativeVelocity * CWeather::WetRoads; + m_sQueueSample.m_nVolume = ComputeVolume(emittingVol, SOUND_INTENSITY, m_sQueueSample.m_fDistance); + if (m_sQueueSample.m_nVolume != 0) { + m_sQueueSample.m_nCounter = 1; + m_sQueueSample.m_nSampleIndex = SFX_ROAD_NOISE; + m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_nReleasingVolumeModificator = 3; + modificator = m_sQueueSample.m_fDistance / 6.f; + freq = SampleManager.GetSampleBaseFrequency(SFX_ROAD_NOISE); + m_sQueueSample.m_nFrequency = freq + freq * modificator; + m_sQueueSample.m_nLoopCount = 0; + m_sQueueSample.m_nEmittingVolume = emittingVol; + m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_fSpeedMultiplier = 6.0f; + m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY; + m_sQueueSample.m_bReleasingSoundFlag = false; + m_sQueueSample.m_nReleasingVolumeDivider = 4; + m_sQueueSample.m_bReverbFlag = true; + m_sQueueSample.m_bRequireReflection = false; + AddSampleToRequestedQueue(); + } + } + } + } + return true; +} + +void +cAudioManager::ProcessVehicleEngine(cVehicleParams *params) +{ + const float SOUND_INTENSITY = 50.0f; + + CVehicle *playerVeh; + CVehicle *veh; + CAutomobile *automobile; + float relativeGearChange; + float relativeChange; + uint8 volume; + int32 freq = 0; // uninitialized variable + uint8 emittingVol; + cTransmission *transmission; + uint8 currentGear; + float modificator; + float traction = 0.f; + + if (params->m_fDistance < SQR(SOUND_INTENSITY)) { + playerVeh = FindPlayerVehicle(); + veh = params->m_pVehicle; + if (playerVeh == veh && veh->GetStatus() == STATUS_WRECKED) { + SampleManager.StopChannel(m_nActiveSamples); + return; + } + if (veh->bEngineOn) { + CalculateDistance(params->m_bDistanceCalculated, params->m_fDistance); + automobile = (CAutomobile *)params->m_pVehicle; + if (params->m_nIndex == DODO) { + ProcessCesna(params); + return; + } + if (FindPlayerVehicle() == veh) { + ProcessPlayersVehicleEngine(params, automobile); + return; + } + transmission = params->m_pTransmission; + if (transmission != nil) { + currentGear = params->m_pVehicle->m_nCurrentGear; + if (automobile->m_nWheelsOnGround != 0) { + if (automobile->bIsHandbrakeOn) { + if (params->m_fVelocityChange == 0.0f) + traction = 0.9f; + } else if (params->m_pVehicle->GetStatus() == STATUS_SIMPLE) { + traction = 0.0f; + } else { + switch (transmission->nDriveType) { + case '4': + for (int32 i = 0; i < ARRAY_SIZE(automobile->m_aWheelState); i++) { + if (automobile->m_aWheelState[i] == WHEEL_STATE_SPINNING) + traction += 0.05f; + } + break; + case 'F': + if (automobile->m_aWheelState[VEHWHEEL_FRONT_LEFT] == WHEEL_STATE_SPINNING) + traction += 0.1f; + if (automobile->m_aWheelState[VEHWHEEL_REAR_LEFT] == WHEEL_STATE_SPINNING) + traction += 0.1f; + break; + case 'R': + if (automobile->m_aWheelState[VEHWHEEL_FRONT_RIGHT] == WHEEL_STATE_SPINNING) + traction += 0.1f; + if (automobile->m_aWheelState[VEHWHEEL_REAR_RIGHT] == WHEEL_STATE_SPINNING) + traction += 0.1f; + break; + } + } + if (transmission->fMaxVelocity <= 0.f) { + relativeChange = 0.f; + } else if (currentGear != 0) { + relativeGearChange = + Min(1.0f, (params->m_fVelocityChange - transmission->Gears[currentGear].fShiftDownVelocity) / transmission->fMaxVelocity * 2.5f); + if (traction == 0.0f && automobile->GetStatus() != STATUS_SIMPLE && + params->m_fVelocityChange >= transmission->Gears[1].fShiftUpVelocity) { + traction = 0.7f; + } + relativeChange = traction * automobile->m_fGasPedalAudio * 0.95f + (1.0f - traction) * relativeGearChange; + } else + relativeChange = + Min(1.0f, 1.0f - Abs((params->m_fVelocityChange - transmission->Gears[0].fShiftDownVelocity) / transmission->fMaxReverseVelocity)); + } else { + if (automobile->m_nDriveWheelsOnGround != 0) + automobile->m_fGasPedalAudio *= 0.4f; + relativeChange = automobile->m_fGasPedalAudio; + } + modificator = relativeChange; + if (currentGear || !automobile->m_nWheelsOnGround) + freq = 1200 * currentGear + 18000.f * modificator + 14000; + else + freq = 13000.f * modificator + 14000; + if (modificator >= 0.75f) { + emittingVol = 120; + volume = ComputeVolume(emittingVol, SOUND_INTENSITY, m_sQueueSample.m_fDistance); + } else { + emittingVol = modificator * 4.0f / 3.0f * 40.f + 80.f; + volume = ComputeVolume(emittingVol, SOUND_INTENSITY, m_sQueueSample.m_fDistance); + } + } else { + modificator = 0.f; + emittingVol = 80; + volume = ComputeVolume(emittingVol, SOUND_INTENSITY, m_sQueueSample.m_fDistance); + } + m_sQueueSample.m_nVolume = volume; + if (m_sQueueSample.m_nVolume != 0) { + if (automobile->GetStatus() == STATUS_SIMPLE) { + if (modificator < 0.02f) { + m_sQueueSample.m_nSampleIndex = aVehicleSettings[params->m_nIndex].m_bEngineSoundType - 1 + SFX_CAR_IDLE_1; + freq = modificator * 10000 + 22050; + m_sQueueSample.m_nCounter = 52; + } else { + m_sQueueSample.m_nSampleIndex = aVehicleSettings[params->m_nIndex].m_nAccelerationSampleIndex; + m_sQueueSample.m_nCounter = 2; + } + } else { + if (automobile->m_fGasPedal < 0.05f) { + m_sQueueSample.m_nSampleIndex = aVehicleSettings[params->m_nIndex].m_bEngineSoundType - 1 + SFX_CAR_IDLE_1; + freq = modificator * 10000 + 22050; + m_sQueueSample.m_nCounter = 52; + } else { + m_sQueueSample.m_nSampleIndex = aVehicleSettings[params->m_nIndex].m_nAccelerationSampleIndex; + m_sQueueSample.m_nCounter = 2; + } + } + m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_nReleasingVolumeModificator = 3; + m_sQueueSample.m_nFrequency = freq + 100 * m_sQueueSample.m_nEntityIndex % 1000; + if (m_sQueueSample.m_nSampleIndex == SFX_CAR_IDLE_6 || m_sQueueSample.m_nSampleIndex == SFX_CAR_REV_6) + m_sQueueSample.m_nFrequency /= 2; + m_sQueueSample.m_nLoopCount = 0; + m_sQueueSample.m_nEmittingVolume = emittingVol; + m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_fSpeedMultiplier = 6.0f; + m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY; + m_sQueueSample.m_bReleasingSoundFlag = false; + m_sQueueSample.m_nReleasingVolumeDivider = 8; + m_sQueueSample.m_bReverbFlag = true; + m_sQueueSample.m_bRequireReflection = false; + AddSampleToRequestedQueue(); + } + } + } +} + +void +cAudioManager::UpdateGasPedalAudio(CAutomobile *automobile) +{ + float gasPedal = Abs(automobile->m_fGasPedal); + float gasPedalAudio = automobile->m_fGasPedalAudio; + + if (gasPedalAudio < gasPedal) + automobile->m_fGasPedalAudio = Min(gasPedalAudio + 0.09f, gasPedal); + else + automobile->m_fGasPedalAudio = Max(gasPedalAudio - 0.07f, gasPedal); +} + +void +cAudioManager::PlayerJustGotInCar() const +{ + if (m_bIsInitialised) + bPlayerJustEnteredCar = true; +} + +void +cAudioManager::PlayerJustLeftCar(void) const +{ + // UNUSED: This is a perfectly empty function. +} + +void +cAudioManager::AddPlayerCarSample(uint8 emittingVolume, int32 freq, uint32 sample, uint8 unk1, uint8 counter, bool notLooping) +{ + m_sQueueSample.m_nVolume = ComputeVolume(emittingVolume, 50.f, m_sQueueSample.m_fDistance); + if (m_sQueueSample.m_nVolume != 0) { + m_sQueueSample.m_nCounter = counter; + m_sQueueSample.m_nSampleIndex = sample; + m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_nReleasingVolumeModificator = 0; + m_sQueueSample.m_nFrequency = freq; + if (notLooping) { + m_sQueueSample.m_nLoopCount = 0; + m_sQueueSample.m_nReleasingVolumeDivider = 8; + } else { + m_sQueueSample.m_nLoopCount = 1; + } + m_sQueueSample.m_nEmittingVolume = emittingVolume; + m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_fSpeedMultiplier = 6.0f; + m_sQueueSample.m_fSoundIntensity = 50.0f; + m_sQueueSample.m_bReleasingSoundFlag = false; + m_sQueueSample.m_bReverbFlag = true; + m_sQueueSample.m_bRequireReflection = false; + AddSampleToRequestedQueue(); + } +} + +void +cAudioManager::ProcessCesna(cVehicleParams *params) +{ + static uint8 nAccel = 0; + + //((CAutomobile *)params->m_pVehicle)->Damage.GetEngineStatus(); + + if (FindPlayerVehicle() == params->m_pVehicle) { + if (params->m_nIndex == DODO) { + if (Pads[0].GetAccelerate() <= 0) { + if (nAccel != 0) + --nAccel; + } else if (nAccel < 60) { + ++nAccel; + } + AddPlayerCarSample(85 * (60 - nAccel) / 60 + 20, 8500 * nAccel / 60 + 17000, SFX_CESNA_IDLE, 0, 52, true); + AddPlayerCarSample(85 * nAccel / 60 + 20, 8500 * nAccel / 60 + 17000, SFX_CESNA_REV, 0, 2, true); + } + } else if (params->m_nIndex == DODO) { + AddPlayerCarSample(105, 17000, SFX_CESNA_IDLE, 0, 52, true); + } else if (params->m_fDistance < SQR(200)) { + CalculateDistance(params->m_bDistanceCalculated, params->m_fDistance); + m_sQueueSample.m_nVolume = ComputeVolume(80, 200.f, m_sQueueSample.m_fDistance); + if (m_sQueueSample.m_nVolume != 0) { + m_sQueueSample.m_nCounter = 52; + m_sQueueSample.m_nSampleIndex = SFX_CESNA_IDLE; + m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_nReleasingVolumeModificator = 0; + m_sQueueSample.m_nFrequency = 12500; + m_sQueueSample.m_nLoopCount = 0; + m_sQueueSample.m_nReleasingVolumeDivider = 8; + m_sQueueSample.m_nEmittingVolume = 80; + m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_fSpeedMultiplier = 8.0f; + m_sQueueSample.m_fSoundIntensity = 200.0f; + m_sQueueSample.m_bReleasingSoundFlag = false; + m_sQueueSample.m_bReverbFlag = true; + m_sQueueSample.m_bRequireReflection = false; + AddSampleToRequestedQueue(); + } + if (params->m_fDistance < SQR(90)) { + m_sQueueSample.m_nVolume = ComputeVolume(80, 90.f, m_sQueueSample.m_fDistance); + if (m_sQueueSample.m_nVolume != 0) { + m_sQueueSample.m_nCounter = 2; + m_sQueueSample.m_nSampleIndex = SFX_CESNA_REV; + m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_nReleasingVolumeModificator = 0; + m_sQueueSample.m_nFrequency = 25000; + m_sQueueSample.m_nLoopCount = 0; + m_sQueueSample.m_nReleasingVolumeDivider = 4; + m_sQueueSample.m_nEmittingVolume = 80; + m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_fSpeedMultiplier = 8.0f; + m_sQueueSample.m_fSoundIntensity = 90.0f; + m_sQueueSample.m_bReleasingSoundFlag = false; + m_sQueueSample.m_bReverbFlag = true; + m_sQueueSample.m_bRequireReflection = false; + AddSampleToRequestedQueue(); + } + } + } +} + +void +cAudioManager::ProcessPlayersVehicleEngine(cVehicleParams *params, CAutomobile *automobile) +{ + static int32 GearFreqAdj[] = {6000, 6000, 3400, 1200, 0, -1000}; + + cTransmission *transmission; + float velocityChange; + float relativeVelocityChange; + float accelerationMultipler; + uint8 wheelInUseCounter; + float time; + int baseFreq; + uint8 vol; + int gearNr; + int32 freq; + + int freqModifier; + int soundOffset; + uint8 engineSoundType; + int16 accelerateState; + bool channelUsed; + bool lostTraction; + bool processedAccelSampleStopped; + uint8 currentGear; + float gasPedalAudio; + CVector pos; + + static int16 LastAccel = 0; + static int16 LastBrake = 0; + static uint8 CurrentPretendGear = 1; + static bool bLostTractionLastFrame = false; + static bool bHandbrakeOnLastFrame = false; + static int32 nCruising = 0; + static bool bAccelSampleStopped = true; + + lostTraction = false; + processedAccelSampleStopped = false; + if (bPlayerJustEnteredCar) { + bAccelSampleStopped = true; + bPlayerJustEnteredCar = false; + nCruising = 0; + LastAccel = 0; + bLostTractionLastFrame = false; + LastBrake = 0; + bHandbrakeOnLastFrame = false; + CurrentPretendGear = 1; + } + if (CReplay::IsPlayingBack()) + accelerateState = 255.f * clamp(automobile->m_fGasPedal, 0.0f, 1.0f); + else + accelerateState = Pads[0].GetAccelerate(); + + channelUsed = SampleManager.GetChannelUsedFlag(m_nActiveSamples); + transmission = params->m_pTransmission; + velocityChange = params->m_fVelocityChange; + relativeVelocityChange = 2.0f * velocityChange / transmission->fMaxVelocity; + + accelerationMultipler = clamp(relativeVelocityChange, 0.0f, 1.0f); + gasPedalAudio = accelerationMultipler; + currentGear = params->m_pVehicle->m_nCurrentGear; + + switch (transmission->nDriveType) + { + case '4': + wheelInUseCounter = 0; + for (uint8 i = 0; i < ARRAY_SIZE(automobile->m_aWheelState); i++) { + if (automobile->m_aWheelState[i] != WHEEL_STATE_NORMAL) + ++wheelInUseCounter; + } + if (wheelInUseCounter > 2) + lostTraction = true; + break; + case 'F': + if ((automobile->m_aWheelState[VEHWHEEL_FRONT_LEFT] != WHEEL_STATE_NORMAL || automobile->m_aWheelState[VEHWHEEL_REAR_LEFT] != WHEEL_STATE_NORMAL) && + (automobile->m_aWheelState[VEHWHEEL_FRONT_RIGHT] != WHEEL_STATE_NORMAL || automobile->m_aWheelState[VEHWHEEL_REAR_RIGHT] != WHEEL_STATE_NORMAL)) + lostTraction = true; + break; + case 'R': + if ((automobile->m_aWheelState[VEHWHEEL_FRONT_RIGHT] != WHEEL_STATE_NORMAL) || (automobile->m_aWheelState[VEHWHEEL_REAR_RIGHT] != WHEEL_STATE_NORMAL)) + lostTraction = true; + break; + } + + if (velocityChange != 0.0f) { + time = params->m_pVehicle->m_vecMoveSpeed.z / velocityChange; + if (time > 0.0f) + freqModifier = -(Min(0.2f, time) * 3000.0f * 5.0f); + else + freqModifier = -(Max(-0.2f, time) * 3000.0f * 5.0f); + if (params->m_fVelocityChange < -0.001f) + freqModifier = -freqModifier; + } else + freqModifier = 0; + + engineSoundType = aVehicleSettings[params->m_nIndex].m_bEngineSoundType; + soundOffset = 3 * (engineSoundType - 1); + if (accelerateState <= 0) { + if (params->m_fVelocityChange < -0.001f) { + if (channelUsed) { + SampleManager.StopChannel(m_nActiveSamples); + bAccelSampleStopped = true; + } + if (!automobile->m_nWheelsOnGround || automobile->bIsHandbrakeOn || lostTraction) + gasPedalAudio = automobile->m_fGasPedalAudio; + else + gasPedalAudio = Min(1.0f, params->m_fVelocityChange / params->m_pTransmission->fMaxReverseVelocity); + + gasPedalAudio = Max(0.0f, gasPedalAudio); + automobile->m_fGasPedalAudio = gasPedalAudio; + } else if (LastAccel > 0) { + if (channelUsed) { + SampleManager.StopChannel(m_nActiveSamples); + bAccelSampleStopped = true; + } + nCruising = 0; + if (!automobile->m_nWheelsOnGround || automobile->bIsHandbrakeOn || lostTraction || + params->m_fVelocityChange >= 0.01f && automobile->m_fGasPedalAudio > 0.2f) { + automobile->m_fGasPedalAudio *= 0.6f; + gasPedalAudio = automobile->m_fGasPedalAudio; + } + if (gasPedalAudio > 0.05f) { + freq = (5000.f * (gasPedalAudio - 0.05f) * 20.f / 19) + 19000; + if (engineSoundType == 6) + freq /= 2; + AddPlayerCarSample((25.f * (gasPedalAudio - 0.05f) * 20.f / 19) + 40, freq, (soundOffset + SFX_CAR_FINGER_OFF_ACCEL_1), engineSoundType, 63, + false); + } + } + freq = (10000.f * gasPedalAudio) + 22050; + if (engineSoundType == 6) + freq /= 2; + AddPlayerCarSample(110 - (40.f * gasPedalAudio), freq, (engineSoundType - 1 + SFX_CAR_IDLE_1), 0, 52, true); + + CurrentPretendGear = Max(1, currentGear); + } else { + while (nCruising == 0) { + if (accelerateState < 150 || !automobile->m_nWheelsOnGround || automobile->bIsHandbrakeOn || lostTraction || + currentGear < 2 && velocityChange - automobile->m_fVelocityChangeForAudio < 0.01f) { // here could be used abs + if (!automobile->m_nWheelsOnGround || automobile->bIsHandbrakeOn || lostTraction) { + if (!automobile->m_nWheelsOnGround && automobile->m_nDriveWheelsOnGround || + (automobile->bIsHandbrakeOn && !bHandbrakeOnLastFrame || lostTraction && !bLostTractionLastFrame) && automobile->m_nWheelsOnGround) { + automobile->m_fGasPedalAudio *= 0.6f; + } + freqModifier = 0; + baseFreq = (15000.f * automobile->m_fGasPedalAudio) + 14000; + vol = (25.0f * automobile->m_fGasPedalAudio) + 60; + } else { + baseFreq = (8000.f * accelerationMultipler) + 16000; + vol = (25.0f * accelerationMultipler) + 60; + automobile->m_fGasPedalAudio = accelerationMultipler; + } + freq = freqModifier + baseFreq; + if (engineSoundType == 6) + freq /= 2; + if (channelUsed) { + SampleManager.StopChannel(m_nActiveSamples); + bAccelSampleStopped = true; + } + AddPlayerCarSample(vol, freq, (engineSoundType - 1 + SFX_CAR_REV_1), 0, 2, true); + } else { + TranslateEntity(&m_sQueueSample.m_vecPos, &pos); + if (bAccelSampleStopped) { + if (CurrentPretendGear != 1 || currentGear != 2) { + gearNr = currentGear - 1; + if (gearNr < 1) + gearNr = 1; + CurrentPretendGear = gearNr; + } + processedAccelSampleStopped = true; + bAccelSampleStopped = false; + } + + if (!channelUsed) { + if (!processedAccelSampleStopped) { + if (CurrentPretendGear < params->m_pTransmission->nNumberOfGears - 1) + ++CurrentPretendGear; + else { + nCruising = 1; + break; // while was used just for this fucking place + } + } + + if (!SampleManager.InitialiseChannel(m_nActiveSamples, soundOffset + SFX_CAR_ACCEL_1, SAMPLEBANK_MAIN)) + return; + SampleManager.SetChannelLoopCount(m_nActiveSamples, 1); + SampleManager.SetChannelLoopPoints(m_nActiveSamples, 0, -1); + } + + SampleManager.SetChannelEmittingVolume(m_nActiveSamples, 85); + SampleManager.SetChannel3DPosition(m_nActiveSamples, pos.x, pos.y, pos.z); + SampleManager.SetChannel3DDistances(m_nActiveSamples, 50.f, 12.5f); + freq = GearFreqAdj[CurrentPretendGear] + freqModifier + 22050; + if (engineSoundType == 6) + freq /= 2; + SampleManager.SetChannelFrequency(m_nActiveSamples, freq); + if (!channelUsed) { + SampleManager.SetChannelReverbFlag(m_nActiveSamples, m_bDynamicAcousticModelingStatus != false); + SampleManager.StartChannel(m_nActiveSamples); + } + } + break; + } + if (nCruising != 0) { + bAccelSampleStopped = true; + if (accelerateState < 150 || !automobile->m_nWheelsOnGround || automobile->bIsHandbrakeOn || lostTraction || + currentGear < params->m_pTransmission->nNumberOfGears - 1) { + nCruising = 0; + } else { + if (accelerateState >= 220 && 0.001f + params->m_fVelocityChange < automobile->m_fVelocityChangeForAudio) { + if (nCruising < 800) + ++nCruising; + } else if (nCruising > 3) { + --nCruising; + } + freq = 27 * nCruising + freqModifier + 22050; + if (engineSoundType == 6) + freq /= 2; + AddPlayerCarSample(85, freq, (soundOffset + SFX_CAR_AFTER_ACCEL_1), engineSoundType, 64, true); + } + } + } + LastAccel = accelerateState; + + bHandbrakeOnLastFrame = !!automobile->bIsHandbrakeOn; + bLostTractionLastFrame = lostTraction; +} + +void +cAudioManager::ProcessVehicleSkidding(cVehicleParams *params) +{ + const float SOUND_INTENSITY = 40.0f; + + CAutomobile *automobile; + cTransmission *transmission; + int32 emittingVol; + float newSkidVal = 0.0f; + float skidVal = 0.0f; + + if (params->m_fDistance >= SQR(SOUND_INTENSITY)) + return; + automobile = (CAutomobile *)params->m_pVehicle; + if (!automobile->m_nWheelsOnGround) + return; + CalculateDistance(params->m_bDistanceCalculated, params->m_fDistance); + for (int32 i = 0; i < ARRAY_SIZE(automobile->m_aWheelState); i++) { + if (automobile->m_aWheelState[i] == WHEEL_STATE_NORMAL || automobile->Damage.GetWheelStatus(i) == WHEEL_STATUS_MISSING) + continue; + transmission = params->m_pTransmission; + switch (transmission->nDriveType) { + case '4': + newSkidVal = GetVehicleDriveWheelSkidValue(i, automobile, transmission, params->m_fVelocityChange); + break; + case 'F': + if (i == CARWHEEL_FRONT_LEFT || i == CARWHEEL_FRONT_RIGHT) + newSkidVal = GetVehicleDriveWheelSkidValue(i, automobile, transmission, params->m_fVelocityChange); + else + newSkidVal = GetVehicleNonDriveWheelSkidValue(i, automobile, transmission, params->m_fVelocityChange); + break; + case 'R': + if (i == CARWHEEL_REAR_LEFT || i == CARWHEEL_REAR_RIGHT) + newSkidVal = GetVehicleDriveWheelSkidValue(i, automobile, transmission, params->m_fVelocityChange); + else + newSkidVal = GetVehicleNonDriveWheelSkidValue(i, automobile, transmission, params->m_fVelocityChange); + break; + default: + break; + } + skidVal = Max(skidVal, newSkidVal); + } + + if (skidVal > 0.0f) { + emittingVol = 50.f * skidVal; + m_sQueueSample.m_nVolume = ComputeVolume(emittingVol, SOUND_INTENSITY, m_sQueueSample.m_fDistance); + if (m_sQueueSample.m_nVolume != 0) { + m_sQueueSample.m_nCounter = 3; + switch (params->m_pVehicle->m_nSurfaceTouched) { + case SURFACE_GRASS: + case SURFACE_HEDGE: + m_sQueueSample.m_nSampleIndex = SFX_RAIN; + emittingVol /= 4; + m_sQueueSample.m_nFrequency = 13000.f * skidVal + 35000.f; + m_sQueueSample.m_nVolume /= 4; + break; + case SURFACE_GRAVEL: + case SURFACE_MUD_DRY: + case SURFACE_SAND: + case SURFACE_WATER: + m_sQueueSample.m_nSampleIndex = SFX_GRAVEL_SKID; + m_sQueueSample.m_nFrequency = 6000.f * skidVal + 10000.f; + break; + + default: + m_sQueueSample.m_nSampleIndex = SFX_SKID; + m_sQueueSample.m_nFrequency = 5000.f * skidVal + 11000.f; + break; + } + + m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_nReleasingVolumeModificator = 8; + m_sQueueSample.m_nLoopCount = 0; + m_sQueueSample.m_nEmittingVolume = emittingVol; + m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_fSpeedMultiplier = 3.0f; + m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY; + m_sQueueSample.m_bReleasingSoundFlag = false; + m_sQueueSample.m_nReleasingVolumeDivider = 3; + m_sQueueSample.m_bReverbFlag = true; + m_sQueueSample.m_bRequireReflection = false; + AddSampleToRequestedQueue(); + } + } +} + +float +cAudioManager::GetVehicleDriveWheelSkidValue(uint8 wheel, CAutomobile *automobile, cTransmission *transmission, float velocityChange) +{ + tWheelState wheelState; + float relativeVelChange; + float gasPedalAudio = automobile->m_fGasPedalAudio; + float modificator; + float velChange; + float relativeVel; + + wheelState = automobile->m_aWheelState[wheel]; + if (wheelState == WHEEL_STATE_SPINNING && gasPedalAudio > 0.4f) { + relativeVelChange = (gasPedalAudio - 0.4f) * 1.25f; + + } else if (wheelState == WHEEL_STATE_SKIDDING) { + relativeVelChange = Min(1.0f, Abs(velocityChange) / transmission->fMaxVelocity); + } else if (wheelState == WHEEL_STATE_FIXED) { + modificator = 0.4f; + relativeVelChange = gasPedalAudio; + if (relativeVelChange > 0.4f) { + relativeVelChange = relativeVelChange - 0.4f; + modificator = 5.f / 3.f; + } + velChange = Abs(velocityChange); + if (relativeVelChange > 0.4f) + relativeVelChange = relativeVelChange * modificator; + if (velChange > 0.04f) { + relativeVel = Min(1.0f, velChange / transmission->fMaxVelocity); + } else { + relativeVel = 0.0f; + } + if (relativeVel >= relativeVelChange) + relativeVelChange = relativeVel; + } else { + relativeVelChange = 0.0f; + } + + return Max(relativeVelChange, Min(1.0f, Abs(automobile->m_vecTurnSpeed.z) * 20.0f)); +} + +float +cAudioManager::GetVehicleNonDriveWheelSkidValue(uint8 wheel, CAutomobile *automobile, cTransmission *transmission, float velocityChange) +{ + float relativeVelChange; + + if (automobile->m_aWheelState[wheel] == WHEEL_STATE_SKIDDING) + relativeVelChange = Min(1.0f, Abs(velocityChange) / transmission->fMaxVelocity); + else + relativeVelChange = 0.0f; + + return Max(relativeVelChange, Min(1.0f, Abs(automobile->m_vecTurnSpeed.z) * 20.0f)); +} + +void +cAudioManager::ProcessVehicleHorn(cVehicleParams *params) +{ + const float SOUND_INTENSITY = 40.0f; + + CAutomobile *automobile; + + if (params->m_fDistance < SQR(SOUND_INTENSITY)) { + automobile = (CAutomobile *)params->m_pVehicle; + if ((!automobile->m_bSirenOrAlarm || !UsesSirenSwitching(params->m_nIndex)) && automobile->GetModelIndex() != MI_MRWHOOP) { + if (automobile->m_nCarHornTimer) { + if (params->m_pVehicle->GetStatus() != STATUS_PLAYER) { + automobile->m_nCarHornTimer = Min(44, automobile->m_nCarHornTimer); + if (automobile->m_nCarHornTimer == 44) + automobile->m_nCarHornPattern = (m_FrameCounter + m_sQueueSample.m_nEntityIndex) & 7; + if (!hornPatternsArray[automobile->m_nCarHornPattern][44 - automobile->m_nCarHornTimer]) + return; + } + + CalculateDistance(params->m_bDistanceCalculated, params->m_fDistance); + m_sQueueSample.m_nVolume = ComputeVolume(80, SOUND_INTENSITY, m_sQueueSample.m_fDistance); + if (m_sQueueSample.m_nVolume != 0) { + m_sQueueSample.m_nCounter = 4; + m_sQueueSample.m_nSampleIndex = aVehicleSettings[params->m_nIndex].m_nHornSample; + m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_nReleasingVolumeModificator = 2; + m_sQueueSample.m_nFrequency = aVehicleSettings[params->m_nIndex].m_nHornFrequency; + m_sQueueSample.m_nLoopCount = 0; + m_sQueueSample.m_nEmittingVolume = 80; + m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_fSpeedMultiplier = 5.0f; + m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY; + m_sQueueSample.m_bReleasingSoundFlag = false; + m_sQueueSample.m_nReleasingVolumeDivider = 3; + m_sQueueSample.m_bReverbFlag = true; + m_sQueueSample.m_bRequireReflection = false; + AddSampleToRequestedQueue(); + } + } + } + } +} + +bool +cAudioManager::UsesSiren(int32 model) const +{ + switch (model) { + case FIRETRUK: + case AMBULAN: + case FBICAR: + case POLICE: + case ENFORCER: + case PREDATOR: + return true; + default: + return false; + } +} + +bool +cAudioManager::UsesSirenSwitching(int32 model) const +{ + switch (model) { + case AMBULAN: + case POLICE: + case ENFORCER: + case PREDATOR: + return true; + default: + return false; + } +} + +void +cAudioManager::ProcessVehicleSirenOrAlarm(cVehicleParams *params) +{ + const float SOUND_INTENSITY = 110.0f; + + if (params->m_fDistance < SQR(SOUND_INTENSITY)) { + CVehicle *veh = params->m_pVehicle; + if (veh->m_bSirenOrAlarm == false && veh->m_nAlarmState <= 0) + return; + +#ifdef FIX_BUGS + if (params->m_pVehicle->GetStatus() == STATUS_WRECKED) + return; +#endif + CalculateDistance(params->m_bDistanceCalculated, params->m_fDistance); + m_sQueueSample.m_nVolume = ComputeVolume(80, SOUND_INTENSITY, m_sQueueSample.m_fDistance); + if (m_sQueueSample.m_nVolume != 0) { + m_sQueueSample.m_nCounter = 5; + if (UsesSiren(params->m_nIndex)) { + if (params->m_pVehicle->GetStatus() == STATUS_ABANDONED) + return; + if (veh->m_nCarHornTimer && params->m_nIndex != FIRETRUK) { + m_sQueueSample.m_nSampleIndex = SFX_SIREN_FAST; + if (params->m_nIndex == FBICAR) + m_sQueueSample.m_nFrequency = 16113; + else + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_SIREN_FAST); + m_sQueueSample.m_nCounter = 60; + } else { + m_sQueueSample.m_nSampleIndex = aVehicleSettings[params->m_nIndex].m_nSirenOrAlarmSample; + m_sQueueSample.m_nFrequency = aVehicleSettings[params->m_nIndex].m_nSirenOrAlarmFrequency; + } + } else { + m_sQueueSample.m_nSampleIndex = aVehicleSettings[params->m_nIndex].m_nSirenOrAlarmSample; + m_sQueueSample.m_nFrequency = aVehicleSettings[params->m_nIndex].m_nSirenOrAlarmFrequency; + } + m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_nReleasingVolumeModificator = 1; + m_sQueueSample.m_nLoopCount = 0; + m_sQueueSample.m_nEmittingVolume = 80; + m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_fSpeedMultiplier = 7.0f; + m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY; + m_sQueueSample.m_bReleasingSoundFlag = false; + m_sQueueSample.m_nReleasingVolumeDivider = 5; + m_sQueueSample.m_bReverbFlag = true; + m_sQueueSample.m_bRequireReflection = false; + AddSampleToRequestedQueue(); + } + } +} + +bool +cAudioManager::UsesReverseWarning(int32 model) const +{ + return model == LINERUN || model == FIRETRUK || model == TRASH || model == BUS || model == COACH; +} + +bool +cAudioManager::ProcessVehicleReverseWarning(cVehicleParams *params) +{ + const float SOUND_INTENSITY = 50.0f; + + CVehicle *veh = params->m_pVehicle; + + if (params->m_fDistance >= SQR(SOUND_INTENSITY)) + return false; + + if (veh->bEngineOn && veh->m_fGasPedal < 0.0f) { + CalculateDistance(params->m_bDistanceCalculated, params->m_fDistance); + m_sQueueSample.m_nVolume = ComputeVolume(60, SOUND_INTENSITY, m_sQueueSample.m_fDistance); + if (m_sQueueSample.m_nVolume != 0) { + m_sQueueSample.m_nCounter = 12; + m_sQueueSample.m_nSampleIndex = SFX_REVERSE_WARNING; + m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_nReleasingVolumeModificator = 2; + m_sQueueSample.m_nFrequency = (100 * m_sQueueSample.m_nEntityIndex & 1023) + SampleManager.GetSampleBaseFrequency(SFX_REVERSE_WARNING); + m_sQueueSample.m_nLoopCount = 0; + m_sQueueSample.m_nEmittingVolume = 60; + m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_fSpeedMultiplier = 3.0f; + m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY; + m_sQueueSample.m_bReleasingSoundFlag = false; + m_sQueueSample.m_nReleasingVolumeDivider = 3; + m_sQueueSample.m_bReverbFlag = true; + m_sQueueSample.m_bRequireReflection = false; + AddSampleToRequestedQueue(); + } + } + return true; +} + +bool +cAudioManager::ProcessVehicleDoors(cVehicleParams *params) +{ + const float SOUND_INTENSITY = 40.0f; + + CAutomobile *automobile; + int8 doorState; + int32 emittingVol; + float velocity; + + if (params->m_fDistance >= SQR(SOUND_INTENSITY)) + return false; + + automobile = (CAutomobile *)params->m_pVehicle; + CalculateDistance(params->m_bDistanceCalculated, params->m_fDistance); + for (int32 i = 0; i < ARRAY_SIZE(automobile->Doors); i++) { + if (automobile->Damage.GetDoorStatus(i) == DOOR_STATUS_SWINGING) { + doorState = automobile->Doors[i].m_nDoorState; + if (doorState == DOORST_OPEN || doorState == DOORST_CLOSED) { + velocity = Min(0.3f, Abs(automobile->Doors[i].m_fAngVel)); + if (velocity > 0.0035f) { + emittingVol = (100.f * velocity * 10.f / 3.f); + m_sQueueSample.m_nVolume = ComputeVolume(emittingVol, SOUND_INTENSITY, m_sQueueSample.m_fDistance); + if (m_sQueueSample.m_nVolume != 0) { + m_sQueueSample.m_nCounter = i + 6; + m_sQueueSample.m_nSampleIndex = m_anRandomTable[1] % 6 + SFX_COL_CAR_PANEL_1; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(m_sQueueSample.m_nSampleIndex) + RandomDisplacement(1000); + m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_nReleasingVolumeModificator = 10; + m_sQueueSample.m_nLoopCount = 1; + m_sQueueSample.m_nEmittingVolume = emittingVol; + m_sQueueSample.m_nLoopStart = 0; + m_sQueueSample.m_nLoopEnd = -1; + m_sQueueSample.m_fSpeedMultiplier = 1.0f; + m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY; + m_sQueueSample.m_bReleasingSoundFlag = true; + m_sQueueSample.m_bReverbFlag = true; + m_sQueueSample.m_bRequireReflection = true; + AddSampleToRequestedQueue(); + } + } + } + } + } + return true; +} + +bool +cAudioManager::ProcessAirBrakes(cVehicleParams *params) +{ + CAutomobile *automobile; + uint8 rand; + + if (params->m_fDistance > SQR(30)) + return false; + automobile = (CAutomobile *)params->m_pVehicle; + if (!automobile->bEngineOn) + return true; + + if ((automobile->m_fVelocityChangeForAudio < 0.025f || params->m_fVelocityChange >= 0.025f) && + (automobile->m_fVelocityChangeForAudio > -0.025f || params->m_fVelocityChange <= 0.025f)) + return true; + + CalculateDistance(params->m_bDistanceCalculated, params->m_fDistance); + rand = m_anRandomTable[0] % 10 + 70; + m_sQueueSample.m_nVolume = ComputeVolume(rand, 30.0f, m_sQueueSample.m_fDistance); + if (m_sQueueSample.m_nVolume != 0) { + m_sQueueSample.m_nCounter = 13; + m_sQueueSample.m_nSampleIndex = SFX_AIR_BRAKES; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_AIR_BRAKES); + m_sQueueSample.m_nFrequency += RandomDisplacement(m_sQueueSample.m_nFrequency / 16); + m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_nReleasingVolumeModificator = 10; + m_sQueueSample.m_nLoopCount = 1; + m_sQueueSample.m_nEmittingVolume = rand; + m_sQueueSample.m_nLoopStart = 0; + m_sQueueSample.m_nLoopEnd = -1; + m_sQueueSample.m_fSpeedMultiplier = 0.0f; + m_sQueueSample.m_fSoundIntensity = 30.0f; + m_sQueueSample.m_bReleasingSoundFlag = true; + m_sQueueSample.m_bReverbFlag = true; + m_sQueueSample.m_bRequireReflection = false; + AddSampleToRequestedQueue(); + } + + return true; +} + +bool +cAudioManager::HasAirBrakes(int32 model) const +{ + return model == LINERUN || model == FIRETRUK || model == TRASH || model == BUS || model == COACH; +} + +bool +cAudioManager::ProcessEngineDamage(cVehicleParams *params) +{ + const int engineDamageIntensity = 40; + + CAutomobile *veh; + uint8 engineStatus; + uint8 emittingVolume; + + if (params->m_fDistance >= SQR(engineDamageIntensity)) + return false; + veh = (CAutomobile *)params->m_pVehicle; + if (veh->bEngineOn) { + engineStatus = veh->Damage.GetEngineStatus(); + if (engineStatus > 250 || engineStatus < 100) + return true; + if (engineStatus < 225) { + m_sQueueSample.m_nSampleIndex = SFX_JUMBO_TAXI; + emittingVolume = 6; + m_sQueueSample.m_nReleasingVolumeModificator = 7; + m_sQueueSample.m_nFrequency = 40000; + } else { + emittingVolume = 60; + m_sQueueSample.m_nSampleIndex = SFX_CAR_ON_FIRE; + m_sQueueSample.m_nReleasingVolumeModificator = 7; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_CAR_ON_FIRE); + } + CalculateDistance(params->m_bDistanceCalculated, params->m_fDistance); + m_sQueueSample.m_nVolume = ComputeVolume(emittingVolume, engineDamageIntensity, m_sQueueSample.m_fDistance); + if (m_sQueueSample.m_nVolume != 0) { + m_sQueueSample.m_nCounter = 28; + m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_nLoopCount = 0; + m_sQueueSample.m_nEmittingVolume = emittingVolume; + m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_fSpeedMultiplier = 2.0f; + m_sQueueSample.m_fSoundIntensity = engineDamageIntensity; + m_sQueueSample.m_bReleasingSoundFlag = false; + m_sQueueSample.m_nReleasingVolumeDivider = 3; + m_sQueueSample.m_bReverbFlag = true; + m_sQueueSample.m_bRequireReflection = false; + AddSampleToRequestedQueue(); + } + } + return true; +} + +bool +cAudioManager::ProcessCarBombTick(cVehicleParams *params) +{ + CAutomobile *automobile; + + if (params->m_fDistance >= SQR(40.f)) + return false; + automobile = (CAutomobile *)params->m_pVehicle; + if (automobile->bEngineOn && automobile->m_bombType == CARBOMB_TIMEDACTIVE) { + CalculateDistance(params->m_bDistanceCalculated, params->m_fDistance); + m_sQueueSample.m_nVolume = ComputeVolume(60, 40.f, m_sQueueSample.m_fDistance); + if (m_sQueueSample.m_nVolume != 0) { + m_sQueueSample.m_nCounter = 35; + m_sQueueSample.m_nSampleIndex = SFX_COUNTDOWN; + m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_nReleasingVolumeModificator = 0; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_COUNTDOWN); + m_sQueueSample.m_nLoopCount = 0; + m_sQueueSample.m_nEmittingVolume = 60; + m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_fSpeedMultiplier = 2.0f; + m_sQueueSample.m_fSoundIntensity = 40.0f; + m_sQueueSample.m_bReleasingSoundFlag = false; + m_sQueueSample.m_nReleasingVolumeDivider = 3; + m_sQueueSample.m_bReverbFlag = true; + m_sQueueSample.m_bRequireReflection = false; + AddSampleToRequestedQueue(); + } + } + return true; +} + +void +cAudioManager::ProcessVehicleOneShots(cVehicleParams *params) +{ + int16 event; + uint8 emittingVol; + float relVol; + float vol; + bool noReflections; + float maxDist; + cPedParams pedParams; + + static uint8 WaveIndex = 41; + static uint8 GunIndex = 53; + static uint8 iWheelIndex = 82; + static uint8 CrunchOffset = 0; + + for (int i = 0; i < m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_AudioEvents; i++) { + noReflections = 0; + m_sQueueSample.m_bRequireReflection = false; + event = m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_awAudioEvent[i]; + switch (event) { + case SOUND_CAR_DOOR_CLOSE_BONNET: + case SOUND_CAR_DOOR_CLOSE_BUMPER: + case SOUND_CAR_DOOR_CLOSE_FRONT_LEFT: + case SOUND_CAR_DOOR_CLOSE_FRONT_RIGHT: + case SOUND_CAR_DOOR_CLOSE_BACK_LEFT: + case SOUND_CAR_DOOR_CLOSE_BACK_RIGHT: { + const float SOUND_INTENSITY = 50.0f; + maxDist = SQR(SOUND_INTENSITY); + emittingVol = m_anRandomTable[2] % 5 + 122; + switch (aVehicleSettings[params->m_nIndex].m_bDoorType) { + case DOOR_TYPE_OLD: + m_sQueueSample.m_nSampleIndex = SFX_OLD_CAR_DOOR_CLOSE; + break; + case DOOR_TYPE_NEW: + default: + m_sQueueSample.m_nSampleIndex = SFX_NEW_CAR_DOOR_CLOSE; + break; + case DOOR_TYPE_TRUCK: + m_sQueueSample.m_nSampleIndex = SFX_TRUCK_DOOR_CLOSE; + break; + case DOOR_TYPE_AIRBREAK: + m_sQueueSample.m_nSampleIndex = SFX_AIR_BRAKES; + break; + } + m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; + m_sQueueSample.m_nCounter = m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_awAudioEvent[i] + 22; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_nFrequency += RandomDisplacement(m_sQueueSample.m_nFrequency / 32); + m_sQueueSample.m_nReleasingVolumeModificator = 3; + m_sQueueSample.m_fSpeedMultiplier = 0.0f; + m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY; + m_sQueueSample.m_bRequireReflection = true; + break; + } + case SOUND_CAR_DOOR_OPEN_BONNET: + case SOUND_CAR_DOOR_OPEN_BUMPER: + case SOUND_CAR_DOOR_OPEN_FRONT_LEFT: + case SOUND_CAR_DOOR_OPEN_FRONT_RIGHT: + case SOUND_CAR_DOOR_OPEN_BACK_LEFT: + case SOUND_CAR_DOOR_OPEN_BACK_RIGHT: { + const float SOUND_INTENSITY = 50.0f; + maxDist = SQR(SOUND_INTENSITY); + emittingVol = m_anRandomTable[1] % 10 + 117; + switch (aVehicleSettings[params->m_nIndex].m_bDoorType) { + case DOOR_TYPE_OLD: + m_sQueueSample.m_nSampleIndex = SFX_OLD_CAR_DOOR_OPEN; + break; + case DOOR_TYPE_NEW: + default: + m_sQueueSample.m_nSampleIndex = SFX_NEW_CAR_DOOR_OPEN; + break; + case DOOR_TYPE_TRUCK: + m_sQueueSample.m_nSampleIndex = SFX_TRUCK_DOOR_OPEN; + break; + case DOOR_TYPE_AIRBREAK: + m_sQueueSample.m_nSampleIndex = SFX_AIR_BRAKES; + break; + } + m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; + m_sQueueSample.m_nCounter = m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_awAudioEvent[i] + 10; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_nFrequency += RandomDisplacement(m_sQueueSample.m_nFrequency / 32); + m_sQueueSample.m_nReleasingVolumeModificator = 3; + m_sQueueSample.m_fSpeedMultiplier = 0.0f; + m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY; + m_sQueueSample.m_bRequireReflection = true; + break; + } + case SOUND_CAR_WINDSHIELD_CRACK: { + const float SOUND_INTENSITY = 30.0f; + maxDist = SQR(SOUND_INTENSITY); + m_sQueueSample.m_nSampleIndex = SFX_GLASS_CRACK; + m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; + m_sQueueSample.m_nCounter = 68; + emittingVol = m_anRandomTable[1] % 30 + 60; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_GLASS_CRACK); + m_sQueueSample.m_nReleasingVolumeModificator = 5; + m_sQueueSample.m_fSpeedMultiplier = 0.0f; + m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY; + } break; + case SOUND_CAR_JUMP: { + const float SOUND_INTENSITY = 35.0f; + emittingVol = Max(80.f, 2 * (100.f * m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_afVolume[i])); + maxDist = SQR(SOUND_INTENSITY); + m_sQueueSample.m_nSampleIndex = SFX_TYRE_BUMP; + m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; + m_sQueueSample.m_nCounter = iWheelIndex++; + if (iWheelIndex > 85) + iWheelIndex = 82; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_TYRE_BUMP); + m_sQueueSample.m_nFrequency += RandomDisplacement(m_sQueueSample.m_nFrequency / 16); + if (params->m_nIndex == RCBANDIT) { + m_sQueueSample.m_nFrequency *= 2; + emittingVol /= 2; + } + m_sQueueSample.m_nReleasingVolumeModificator = 6; + m_sQueueSample.m_fSpeedMultiplier = 2.0f; + m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY; + break; + } + case SOUND_CAR_ENGINE_START: { + const float SOUND_INTENSITY = 40.0f; + emittingVol = 60; + maxDist = SQR(SOUND_INTENSITY); + m_sQueueSample.m_nSampleIndex = SFX_CAR_STARTER; + m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; + m_sQueueSample.m_nCounter = 33; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_CAR_STARTER); + m_sQueueSample.m_nReleasingVolumeModificator = 1; + m_sQueueSample.m_fSpeedMultiplier = 2.0f; + m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY; + m_sQueueSample.m_bRequireReflection = true; + break; + } + case SOUND_CAR_LIGHT_BREAK: { + const float SOUND_INTENSITY = 30.0f; + m_sQueueSample.m_nSampleIndex = SFX_GLASS_SHARD_1; + m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; + m_sQueueSample.m_nCounter = 37; + m_sQueueSample.m_nFrequency = 9 * SampleManager.GetSampleBaseFrequency(SFX_GLASS_SHARD_1) / 10; + m_sQueueSample.m_nFrequency += RandomDisplacement(m_sQueueSample.m_nFrequency / 8); + m_sQueueSample.m_nReleasingVolumeModificator = 5; + m_sQueueSample.m_fSpeedMultiplier = 0.0f; + m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY; + maxDist = SQR(SOUND_INTENSITY); + emittingVol = m_anRandomTable[4] % 10 + 30; + break; + } + case SOUND_CAR_HYDRAULIC_1: + case SOUND_CAR_HYDRAULIC_2: { + const float SOUND_INTENSITY = 35.0f; + if (event == SOUND_CAR_HYDRAULIC_1) + m_sQueueSample.m_nFrequency = 15600; + else + m_sQueueSample.m_nFrequency = 13118; + m_sQueueSample.m_nSampleIndex = SFX_SUSPENSION_FAST_MOVE; + m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; + m_sQueueSample.m_nCounter = 51; + m_sQueueSample.m_nFrequency += RandomDisplacement(m_sQueueSample.m_nFrequency / 8); + m_sQueueSample.m_nReleasingVolumeModificator = 5; + m_sQueueSample.m_fSpeedMultiplier = 0.0f; + m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY; + maxDist = SQR(SOUND_INTENSITY); + emittingVol = m_anRandomTable[0] % 15 + 55; + break; + } + case SOUND_CAR_HYDRAULIC_3: { + const float SOUND_INTENSITY = 35.0f; + m_sQueueSample.m_nSampleIndex = SFX_SUSPENSION_SLOW_MOVE_LOOP; + m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; + m_sQueueSample.m_nCounter = 86; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_SUSPENSION_SLOW_MOVE_LOOP); + m_sQueueSample.m_nReleasingVolumeModificator = 5; + m_sQueueSample.m_fSpeedMultiplier = 0.0f; + m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY; + m_sQueueSample.m_nReleasingVolumeDivider = 7; + noReflections = true; + maxDist = SQR(SOUND_INTENSITY); + emittingVol = m_anRandomTable[0] % 15 + 55; + break; + } + case SOUND_CAR_JERK: { + const float SOUND_INTENSITY = 35.0f; + m_sQueueSample.m_nSampleIndex = SFX_SHAG_SUSPENSION; + m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; + m_sQueueSample.m_nCounter = 87; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_SHAG_SUSPENSION); + m_sQueueSample.m_nFrequency += RandomDisplacement(m_sQueueSample.m_nFrequency / 8); + m_sQueueSample.m_nReleasingVolumeModificator = 5; + m_sQueueSample.m_fSpeedMultiplier = 0.0f; + m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY; + maxDist = SQR(SOUND_INTENSITY); + emittingVol = m_anRandomTable[1] % 15 + 55; + break; + } + case SOUND_CAR_SPLASH: { + const float SOUND_INTENSITY = 40.0f; + vol = m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_afVolume[i]; + if (vol <= 300.f) + continue; + if (vol > 1200.f) + m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_afVolume[i] = 1200.0f; + relVol = (m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_afVolume[i] - 300.f) / 900.f; + m_sQueueSample.m_nSampleIndex = (m_anRandomTable[0] & 1) + SFX_BOAT_SPLASH_1; + m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; + m_sQueueSample.m_nCounter = WaveIndex++; + if (WaveIndex > 46) + WaveIndex = 41; + m_sQueueSample.m_nFrequency = (7000.f * relVol) + 6000; + m_sQueueSample.m_nReleasingVolumeModificator = 3; + m_sQueueSample.m_fSpeedMultiplier = 2.0f; + m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY; + emittingVol = (55.f * relVol); + maxDist = SQR(SOUND_INTENSITY); + break; + } + case SOUND_17: { + const float SOUND_INTENSITY = 50.0f; + m_sQueueSample.m_nSampleIndex = SFX_POLICE_BOAT_THUMB_OFF; + m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; + m_sQueueSample.m_nCounter = 47; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_POLICE_BOAT_THUMB_OFF) + RandomDisplacement(600); + m_sQueueSample.m_nReleasingVolumeModificator = 2; + m_sQueueSample.m_fSpeedMultiplier = 0.0f; + m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY; + emittingVol = m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_afVolume[i]; + maxDist = SQR(SOUND_INTENSITY); + break; + } + case SOUND_18: + case SOUND_19: { + const float SOUND_INTENSITY = 35.0f; + m_sQueueSample.m_nSampleIndex = SFX_AIR_BRAKES; + m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; + m_sQueueSample.m_nCounter = 59; + m_sQueueSample.m_nFrequency = RandomDisplacement(1000) + 11025; + m_sQueueSample.m_nReleasingVolumeModificator = 5; + m_sQueueSample.m_fSpeedMultiplier = 5.0f; + m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY; + maxDist = SQR(SOUND_INTENSITY); + emittingVol = m_anRandomTable[1] % 20 + 70; + break; + } + case SOUND_CAR_TANK_TURRET_ROTATE: { + const float SOUND_INTENSITY = 40.0f; + vol = m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_afVolume[i]; + if (vol > 96.0f / 2500.0f) + vol = 96.0f / 2500.0f; + m_sQueueSample.m_nSampleIndex = SFX_TANK_TURRET; + m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; + m_sQueueSample.m_nCounter = 79; + m_sQueueSample.m_nFrequency = (3000.f * vol * 2500.0f / 96.0f) + 9000; + m_sQueueSample.m_nReleasingVolumeModificator = 2; + m_sQueueSample.m_fSpeedMultiplier = 2.0f; + m_sQueueSample.m_nReleasingVolumeDivider = 3; + m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY; + emittingVol = (37.f * vol * 2500.0f / 96.0f) + 90; + maxDist = SQR(SOUND_INTENSITY); + noReflections = true; + break; + } + case SOUND_CAR_BOMB_TICK: { + const float SOUND_INTENSITY = 30.0f; + m_sQueueSample.m_nSampleIndex = SFX_BOMB_BEEP; + m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; + m_sQueueSample.m_nCounter = 80; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_BOMB_BEEP); + m_sQueueSample.m_nReleasingVolumeModificator = 3; + m_sQueueSample.m_fSpeedMultiplier = 0.0f; + m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY; + maxDist = SQR(SOUND_INTENSITY); + m_sQueueSample.m_bRequireReflection = true; + emittingVol = 60; + break; + } + case SOUND_PLANE_ON_GROUND: { + const float SOUND_INTENSITY = 180.0f; + m_sQueueSample.m_nSampleIndex = SFX_JUMBO_LAND_WHEELS; + m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; + m_sQueueSample.m_nCounter = 81; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_JUMBO_LAND_WHEELS); + m_sQueueSample.m_nReleasingVolumeModificator = 2; + m_sQueueSample.m_fSpeedMultiplier = 0.0f; + m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY; + maxDist = SQR(SOUND_INTENSITY); + emittingVol = m_anRandomTable[4] % 25 + 75; + break; + } + case SOUND_WEAPON_SHOT_FIRED: { + const float SOUND_INTENSITY = 120.0f; + emittingVol = m_anRandomTable[2]; + maxDist = SQR(SOUND_INTENSITY); + m_sQueueSample.m_nSampleIndex = SFX_UZI_LEFT; + m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; + m_sQueueSample.m_nCounter = GunIndex++; + emittingVol = emittingVol % 15 + 65; + if (GunIndex > 58) + GunIndex = 53; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_UZI_LEFT); + m_sQueueSample.m_nFrequency += RandomDisplacement(m_sQueueSample.m_nFrequency / 16); + m_sQueueSample.m_nReleasingVolumeModificator = 3; + m_sQueueSample.m_fSpeedMultiplier = 0.0f; + m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY; + break; + } + case SOUND_WEAPON_HIT_VEHICLE: { + const float SOUND_INTENSITY = 40.0f; + m_sQueueSample.m_nSampleIndex = m_anRandomTable[m_sQueueSample.m_nEntityIndex % ARRAY_SIZE(m_anRandomTable)] % 6 + SFX_BULLET_CAR_1; + m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; + m_sQueueSample.m_nCounter = 34; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_nFrequency += RandomDisplacement(m_sQueueSample.m_nFrequency / 32); + m_sQueueSample.m_nReleasingVolumeModificator = 7; + m_sQueueSample.m_fSpeedMultiplier = 0.0f; + m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY; + maxDist = SQR(SOUND_INTENSITY); + emittingVol = m_anRandomTable[3] % 20 + 90; + break; + } + case SOUND_BOMB_TIMED_ACTIVATED: + case SOUND_55: + case SOUND_BOMB_ONIGNITION_ACTIVATED: + case SOUND_BOMB_TICK: { + const float SOUND_INTENSITY = 50.0f; + m_sQueueSample.m_nSampleIndex = SFX_ARM_BOMB; + m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; + m_sQueueSample.m_nCounter = 36; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_ARM_BOMB); + m_sQueueSample.m_nReleasingVolumeModificator = 0; + m_sQueueSample.m_fSpeedMultiplier = 0.0f; + m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY; + m_sQueueSample.m_bRequireReflection = true; + emittingVol = 50; + maxDist = SQR(SOUND_INTENSITY); + break; + } + case SOUND_PED_HELI_PLAYER_FOUND: + pedParams.m_pPed = nil; + pedParams.m_bDistanceCalculated = false; + pedParams.m_fDistance = 0.0f; + pedParams.m_bDistanceCalculated = params->m_bDistanceCalculated; + pedParams.m_fDistance = params->m_fDistance; + SetupPedComments(&pedParams, SOUND_PED_HELI_PLAYER_FOUND); + continue; + case SOUND_PED_BODYCAST_HIT: + pedParams.m_pPed = nil; + pedParams.m_bDistanceCalculated = false; + pedParams.m_fDistance = 0.0f; + pedParams.m_bDistanceCalculated = params->m_bDistanceCalculated; + pedParams.m_fDistance = params->m_fDistance; + SetupPedComments(&pedParams, SOUND_PED_BODYCAST_HIT); + continue; + case SOUND_WATER_FALL: { + const float SOUND_INTENSITY = 40.0f; + m_sQueueSample.m_nSampleIndex = SFX_SPLASH_1; + m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; + m_sQueueSample.m_nCounter = 15; + m_sQueueSample.m_nFrequency = RandomDisplacement(1000) + 16000; + m_sQueueSample.m_nReleasingVolumeModificator = 1; + m_sQueueSample.m_fSpeedMultiplier = 0.0f; + m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY; + maxDist = SQR(SOUND_INTENSITY); + m_sQueueSample.m_bRequireReflection = true; + emittingVol = m_anRandomTable[4] % 20 + 90; + break; + } + case SOUND_SPLATTER: { + const float SOUND_INTENSITY = 40.0f; + m_sQueueSample.m_nSampleIndex = CrunchOffset + SFX_PED_CRUNCH_1; + m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; + m_sQueueSample.m_nCounter = 48; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_PED_CRUNCH_1) + RandomDisplacement(600); + m_sQueueSample.m_nReleasingVolumeModificator = 1; + m_sQueueSample.m_fSpeedMultiplier = 0.0f; + m_sQueueSample.m_fSoundIntensity = 40.0f; + ++CrunchOffset; + maxDist = SQR(SOUND_INTENSITY); + emittingVol = m_anRandomTable[4] % 20 + 55; + CrunchOffset %= 2; + m_sQueueSample.m_bRequireReflection = true; + break; + } + case SOUND_CAR_PED_COLLISION: { + const float SOUND_INTENSITY = 40.0f; + vol = Min(20.0f, m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_afVolume[i]); + emittingVol = (vol / 20.0f * 127.f); + if (!emittingVol) + continue; + + m_sQueueSample.m_nSampleIndex = (m_anRandomTable[2] & 3) + SFX_FIGHT_1; + m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; + m_sQueueSample.m_nCounter = 50; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(m_sQueueSample.m_nSampleIndex) / 2; + m_sQueueSample.m_nReleasingVolumeModificator = 1; + m_sQueueSample.m_fSpeedMultiplier = 0.0f; + m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY; + maxDist = SQR(SOUND_INTENSITY); + break; + } + default: + continue; + } + if (params->m_fDistance < maxDist) { + CalculateDistance(params->m_bDistanceCalculated, params->m_fDistance); + m_sQueueSample.m_nVolume = ComputeVolume(emittingVol, m_sQueueSample.m_fSoundIntensity, m_sQueueSample.m_fDistance); + if (m_sQueueSample.m_nVolume != 0) { + if (noReflections) { + m_sQueueSample.m_nLoopCount = 0; + m_sQueueSample.m_bReleasingSoundFlag = false; + } else { + m_sQueueSample.m_nLoopCount = 1; + m_sQueueSample.m_bReleasingSoundFlag = true; + } + m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_nEmittingVolume = emittingVol; + m_sQueueSample.m_bReverbFlag = true; + m_sQueueSample.m_bIs2D = false; + AddSampleToRequestedQueue(); + } + } + } +} + +bool +cAudioManager::ProcessTrainNoise(cVehicleParams *params) +{ + const float SOUND_INTENSITY = 300.0f; + + CTrain *train; + uint8 emittingVol; + float speedMultipler; + + if (params->m_fDistance >= SQR(SOUND_INTENSITY)) + return false; + + if (params->m_fVelocityChange > 0.0f) { + CalculateDistance(params->m_bDistanceCalculated, params->m_fDistance); + train = (CTrain *)params->m_pVehicle; + speedMultipler = Min(1.0f, train->m_fSpeed * 250.f / 51.f); + emittingVol = (75.f * speedMultipler); + if (train->m_fWagonPosition == 0.0f) { + m_sQueueSample.m_nVolume = ComputeVolume(emittingVol, SOUND_INTENSITY, m_sQueueSample.m_fDistance); + if (m_sQueueSample.m_nVolume != 0) { + m_sQueueSample.m_nCounter = 32; + m_sQueueSample.m_nSampleIndex = SFX_TRAIN_FAR; + m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_nReleasingVolumeModificator = 2; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_TRAIN_FAR); + m_sQueueSample.m_nLoopCount = 0; + m_sQueueSample.m_nEmittingVolume = emittingVol; + m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_fSpeedMultiplier = 3.0f; + m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY; + m_sQueueSample.m_bReleasingSoundFlag = false; + m_sQueueSample.m_nReleasingVolumeDivider = 3; + m_sQueueSample.m_bReverbFlag = true; + m_sQueueSample.m_bRequireReflection = false; + AddSampleToRequestedQueue(); + } + } + const float SOUND_INTENSITY = 70.0f; + if (params->m_fDistance < SQR(SOUND_INTENSITY)) { + m_sQueueSample.m_nVolume = ComputeVolume(emittingVol, SOUND_INTENSITY, m_sQueueSample.m_fDistance); + if (m_sQueueSample.m_nVolume != 0) { + m_sQueueSample.m_nCounter = 33; + m_sQueueSample.m_nSampleIndex = SFX_TRAIN_NEAR; + m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_nReleasingVolumeModificator = 5; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_TRAIN_NEAR) + 100 * m_sQueueSample.m_nEntityIndex % 987; + m_sQueueSample.m_nLoopCount = 0; + m_sQueueSample.m_nEmittingVolume = emittingVol; + m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_fSpeedMultiplier = 6.0f; + m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY; + m_sQueueSample.m_bReleasingSoundFlag = false; + m_sQueueSample.m_nReleasingVolumeDivider = 3; + m_sQueueSample.m_bReverbFlag = true; + m_sQueueSample.m_bRequireReflection = false; + AddSampleToRequestedQueue(); + } + } + } + return true; +} + +bool +cAudioManager::ProcessBoatEngine(cVehicleParams *params) +{ + CBoat *boat; + float padRelativeAccerate; + float gasPedal; + int32 padAccelerate; + uint8 emittingVol; + float oneShotVol; + + static uint16 LastAccel = 0; + static uint8 LastVol = 0; + + static const int intensity = 50; + + if (params->m_fDistance < SQR(intensity)) { + boat = (CBoat *)params->m_pVehicle; + if (params->m_nIndex == REEFER) { + CalculateDistance(params->m_bDistanceCalculated, params->m_fDistance); + m_sQueueSample.m_nVolume = ComputeVolume(80, 50.f, m_sQueueSample.m_fDistance); + if (m_sQueueSample.m_nVolume != 0) { + m_sQueueSample.m_nCounter = 39; + m_sQueueSample.m_nSampleIndex = SFX_FISHING_BOAT_IDLE; + m_sQueueSample.m_nFrequency = 10386; + m_sQueueSample.m_nFrequency += (m_sQueueSample.m_nEntityIndex * 65536) % 1000; + m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_nReleasingVolumeModificator = 3; + m_sQueueSample.m_nLoopCount = 0; + m_sQueueSample.m_nEmittingVolume = 80; + m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_fSpeedMultiplier = 2.0f; + m_sQueueSample.m_fSoundIntensity = intensity; + m_sQueueSample.m_bReleasingSoundFlag = false; + m_sQueueSample.m_nReleasingVolumeDivider = 7; + m_sQueueSample.m_bReverbFlag = true; + m_sQueueSample.m_bRequireReflection = false; + AddSampleToRequestedQueue(); + } + if (FindPlayerVehicle() == params->m_pVehicle) { + if (Pads[0].GetAccelerate() <= Pads[0].GetBrake()) + padAccelerate = Pads[0].GetBrake(); + else + padAccelerate = Pads[0].GetAccelerate(); + padRelativeAccerate = padAccelerate / 255; + emittingVol = (100.f * padRelativeAccerate) + 15; + m_sQueueSample.m_nFrequency = (3000.f * padRelativeAccerate) + 6000; + if (!boat->m_bIsAnchored) + m_sQueueSample.m_nFrequency = 11 * m_sQueueSample.m_nFrequency / 10; + } else { + gasPedal = Abs(boat->m_fGasPedal); + if (gasPedal > 0.0f) { + m_sQueueSample.m_nFrequency = 6000; + emittingVol = 15; + } else { + emittingVol = (100.f * gasPedal) + 15; + m_sQueueSample.m_nFrequency = (3000.f * gasPedal) + 6000; + if (!boat->m_bIsAnchored) + m_sQueueSample.m_nFrequency = 11 * m_sQueueSample.m_nFrequency / 10; + } + } + m_sQueueSample.m_nVolume = ComputeVolume(emittingVol, 50.f, m_sQueueSample.m_fDistance); + if (!m_sQueueSample.m_nVolume) + return true; + m_sQueueSample.m_nCounter = 40; + m_sQueueSample.m_nSampleIndex = SFX_POLICE_BOAT_ACCEL; + m_sQueueSample.m_nFrequency += (m_sQueueSample.m_nEntityIndex * 65536) % 1000; + m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_nReleasingVolumeModificator = 3; + m_sQueueSample.m_nLoopCount = 0; + m_sQueueSample.m_nEmittingVolume = emittingVol; + m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_fSpeedMultiplier = 2.0f; + m_sQueueSample.m_fSoundIntensity = intensity; + m_sQueueSample.m_bReleasingSoundFlag = false; + m_sQueueSample.m_nReleasingVolumeDivider = 7; + m_sQueueSample.m_bReverbFlag = true; + m_sQueueSample.m_bRequireReflection = false; + } else { + if (FindPlayerVehicle() == params->m_pVehicle) { + if (Pads[0].GetAccelerate() <= Pads[0].GetBrake()) + padAccelerate = Pads[0].GetBrake(); + else + padAccelerate = Pads[0].GetAccelerate(); + if (padAccelerate <= 20) { + emittingVol = 45 - 45 * padAccelerate / 40; + m_sQueueSample.m_nFrequency = 100 * padAccelerate + 11025; + m_sQueueSample.m_nCounter = 39; + m_sQueueSample.m_nSampleIndex = SFX_POLICE_BOAT_IDLE; + if (LastAccel > 20) { + oneShotVol = LastVol; + PlayOneShot(m_sQueueSample.m_nEntityIndex, SOUND_17, oneShotVol); + } + } else { + emittingVol = 105 * padAccelerate / 255 + 15; + m_sQueueSample.m_nFrequency = 4000 * padAccelerate / 255 + 8000; + if (!boat->m_bIsAnchored) + m_sQueueSample.m_nFrequency = 11 * m_sQueueSample.m_nFrequency / 10; + m_sQueueSample.m_nCounter = 40; + m_sQueueSample.m_nSampleIndex = SFX_POLICE_BOAT_ACCEL; + } + LastVol = emittingVol; + LastAccel = padAccelerate; + } else { + gasPedal = Abs(boat->m_fGasPedal); + if (gasPedal > 0.0f) { + m_sQueueSample.m_nFrequency = 11025; + emittingVol = 45; + m_sQueueSample.m_nCounter = 39; + m_sQueueSample.m_nSampleIndex = SFX_POLICE_BOAT_IDLE; + } else { + emittingVol = (105.f * gasPedal) + 15; + m_sQueueSample.m_nFrequency = (4000.f * gasPedal) + 8000; + if (!boat->m_bIsAnchored) + m_sQueueSample.m_nFrequency = 11 * m_sQueueSample.m_nFrequency / 10; + m_sQueueSample.m_nCounter = 40; + m_sQueueSample.m_nSampleIndex = SFX_POLICE_BOAT_ACCEL; + } + } + CalculateDistance(params->m_bDistanceCalculated, params->m_fDistance); + m_sQueueSample.m_nVolume = ComputeVolume(emittingVol, 50.f, m_sQueueSample.m_fDistance); + if (!m_sQueueSample.m_nVolume) + return true; + m_sQueueSample.m_nFrequency += (m_sQueueSample.m_nEntityIndex * 65536) % 1000; + m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_nReleasingVolumeModificator = 3; + m_sQueueSample.m_nLoopCount = 0; + m_sQueueSample.m_nEmittingVolume = emittingVol; + m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_fSpeedMultiplier = 2.0f; + m_sQueueSample.m_fSoundIntensity = intensity; + m_sQueueSample.m_bReleasingSoundFlag = false; + m_sQueueSample.m_nReleasingVolumeDivider = 7; + m_sQueueSample.m_bReverbFlag = true; + m_sQueueSample.m_bRequireReflection = false; + } + AddSampleToRequestedQueue(); + return true; + } + return false; +} + +bool +cAudioManager::ProcessBoatMovingOverWater(cVehicleParams *params) +{ + float velocityChange; + int32 vol; + float multiplier; + + if (params->m_fDistance > SQR(50)) + return false; + + velocityChange = Abs(params->m_fVelocityChange); + if (velocityChange <= 0.0005f && ((CBoat*)params->m_pVehicle)->bBoatInWater) + return true; + + velocityChange = Min(0.75f, velocityChange); + multiplier = (velocityChange - 0.0005f) * 1.3342f; + CalculateDistance(params->m_bDistanceCalculated, params->m_fDistance); + vol = (30.f * multiplier); + m_sQueueSample.m_nVolume = ComputeVolume(vol, 50.f, m_sQueueSample.m_fDistance); + if (m_sQueueSample.m_nVolume != 0) { + m_sQueueSample.m_nCounter = 38; + m_sQueueSample.m_nSampleIndex = SFX_BOAT_WATER_LOOP; + m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_nReleasingVolumeModificator = 3; + m_sQueueSample.m_nFrequency = (6050.f * multiplier) + 16000; + m_sQueueSample.m_nLoopCount = 0; + m_sQueueSample.m_nEmittingVolume = vol; + m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_fSpeedMultiplier = 2.0f; + m_sQueueSample.m_fSoundIntensity = 50.0f; + m_sQueueSample.m_bReleasingSoundFlag = false; + m_sQueueSample.m_nReleasingVolumeDivider = 3; + m_sQueueSample.m_bReverbFlag = true; + m_sQueueSample.m_bRequireReflection = false; + AddSampleToRequestedQueue(); + } + + return true; +} + +struct tHelicopterSampleData { + float m_fMaxDistance; + float m_fBaseDistance; + uint8 m_bBaseVolume; +}; + +bool +cAudioManager::ProcessHelicopter(cVehicleParams *params) +{ + CHeli *heli; + float MaxDist; + float dist; + float baseDist; + int32 emittingVol; + static const tHelicopterSampleData gHeliSfxRanges[3] = {{400.f, 380.f, 100}, {100.f, 70.f, MAX_VOLUME}, {60.f, 30.f, MAX_VOLUME}}; + + if (SQR(gHeliSfxRanges[0].m_fMaxDistance) <= params->m_fDistance) + return false; + + CalculateDistance(params->m_bDistanceCalculated, params->m_fDistance); + heli = (CHeli *)params->m_pVehicle; + for (uint32 i = 0; i < ARRAY_SIZE(gHeliSfxRanges); i++) { + MaxDist = gHeliSfxRanges[i].m_fMaxDistance; + dist = m_sQueueSample.m_fDistance; + if (dist >= MaxDist) + return true; + baseDist = gHeliSfxRanges[i].m_fBaseDistance; + if (dist < baseDist) + emittingVol = (gHeliSfxRanges[i].m_bBaseVolume * ((MaxDist - dist) / (MaxDist - baseDist))); + else + emittingVol = gHeliSfxRanges[i].m_bBaseVolume; + + m_sQueueSample.m_nVolume = ComputeVolume(emittingVol, gHeliSfxRanges[i].m_fMaxDistance, m_sQueueSample.m_fDistance); + if (m_sQueueSample.m_nVolume != 0) { + m_sQueueSample.m_nCounter = i + 65; + m_sQueueSample.m_nSampleIndex = i + SFX_HELI_1; + m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_nReleasingVolumeModificator = 0; + m_sQueueSample.m_nFrequency = 1200 * heli->m_nHeliId + SampleManager.GetSampleBaseFrequency(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_nLoopCount = 0; + m_sQueueSample.m_nEmittingVolume = emittingVol; + m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_fSpeedMultiplier = 6.0f; + m_sQueueSample.m_fSoundIntensity = gHeliSfxRanges[i].m_fMaxDistance; + m_sQueueSample.m_bReleasingSoundFlag = false; + m_sQueueSample.m_nReleasingVolumeDivider = 3; + m_sQueueSample.m_bReverbFlag = true; + m_sQueueSample.m_bRequireReflection = false; + AddSampleToRequestedQueue(); + } + } + return true; +} + +void +cAudioManager::ProcessPlane(cVehicleParams *params) +{ + switch (params->m_nIndex) { + case AIRTRAIN: + ProcessJumbo(params); + break; + case DEADDODO: + ProcessCesna(params); + break; + default: + debug("Plane Model Id is %d\n, ", params->m_pVehicle->GetModelIndex()); + break; + } +} + +#pragma region JUMBO +uint8 gJumboVolOffsetPercentage; + +void +DoJumboVolOffset() +{ + if (!(AudioManager.GetFrameCounter() % (AudioManager.GetRandomNumber(0) % 6 + 3))) + gJumboVolOffsetPercentage = AudioManager.GetRandomNumber(1) % 60; +} + +void +cAudioManager::ProcessJumbo(cVehicleParams *params) +{ + CPlane *plane; + float position; + + if (params->m_fDistance < SQR(440)) { + CalculateDistance(params->m_bDistanceCalculated, params->m_fDistance); + plane = (CPlane *)params->m_pVehicle; + DoJumboVolOffset(); + position = PlanePathPosition[plane->m_nPlaneId]; + if (position <= TakeOffPoint) { + if (plane->m_fSpeed <= 0.10334f) { + ProcessJumboTaxi(); + return; + } + + ProcessJumboAccel(plane); + } else if (300.0f + TakeOffPoint >= position) { + ProcessJumboTakeOff(plane); + } else if (LandingPoint - 350.0f >= position) { + ProcessJumboFlying(); + } else { + if (position > LandingPoint) { + if (plane->m_fSpeed > 0.10334f) { + ProcessJumboDecel(plane); + return; + } + ProcessJumboTaxi(); + return; + } + ProcessJumboLanding(plane); + } + } +} + +void +cAudioManager::ProcessJumboTaxi() +{ + if (SetupJumboFlySound(20)) { + if (SetupJumboTaxiSound(75)) + SetupJumboWhineSound(18, 29500); + } +} + +void +cAudioManager::ProcessJumboAccel(CPlane *plane) +{ + int32 engineFreq; + int32 vol; + float whineSoundFreq; + float modificator; + + if (SetupJumboFlySound(20)) { + modificator = (plane->m_fSpeed - 0.10334f) * 1.676f; + if (modificator > 1.0f) + modificator = 1.0f; + if (SetupJumboRumbleSound(MAX_VOLUME * modificator) && SetupJumboTaxiSound((1.0f - modificator) * 75.f)) { + if (modificator < 0.2f) { + whineSoundFreq = modificator * 5.f * 14600.0f + 29500; + vol = modificator * 5.f * MAX_VOLUME; + engineFreq = modificator * 5.f * 6050.f + 16000; + } else { + whineSoundFreq = 44100; + engineFreq = 22050; + vol = MAX_VOLUME; + } + SetupJumboEngineSound(vol, engineFreq); + SetupJumboWhineSound(18, whineSoundFreq); + } + } +} + +void +cAudioManager::ProcessJumboTakeOff(CPlane *plane) +{ + const float modificator = (PlanePathPosition[plane->m_nPlaneId] - TakeOffPoint) / 300.f; + + if (SetupJumboFlySound((107.f * modificator) + 20) && SetupJumboRumbleSound(MAX_VOLUME * (1.f - modificator))) { + if (SetupJumboEngineSound(MAX_VOLUME, 22050)) + SetupJumboWhineSound(18.f * (1.f - modificator), 44100); + } +} + +void +cAudioManager::ProcessJumboFlying() +{ + if (SetupJumboFlySound(MAX_VOLUME)) + SetupJumboEngineSound(63, 22050); +} + +void +cAudioManager::ProcessJumboLanding(CPlane *plane) +{ + const float modificator = (LandingPoint - PlanePathPosition[plane->m_nPlaneId]) / 350.f; + if (SetupJumboFlySound(107.f * modificator + 20)) { + if (SetupJumboTaxiSound(75.f * (1.f - modificator))) { + SetupJumboEngineSound(MAX_VOLUME, 22050); + SetupJumboWhineSound(18.f * (1.f - modificator), 14600.f * modificator + 29500); + } + } +} + +void +cAudioManager::ProcessJumboDecel(CPlane *plane) +{ + if (SetupJumboFlySound(20) && SetupJumboTaxiSound(75)) { + const float modificator = Min(1.f, (plane->m_fSpeed - 0.10334f) * 1.676f); + SetupJumboEngineSound(MAX_VOLUME * modificator, 6050.f * modificator + 16000); + SetupJumboWhineSound(18, 29500); + } +} + +bool +cAudioManager::SetupJumboTaxiSound(uint8 vol) +{ + const float SOUND_INTENSITY = 180.0f; + if (m_sQueueSample.m_fDistance >= SOUND_INTENSITY) + return false; + + uint8 emittingVol = (vol / 2) + ((vol / 2) * m_sQueueSample.m_fDistance / SOUND_INTENSITY); + + if (m_sQueueSample.m_fDistance / SOUND_INTENSITY < 0.7f) + emittingVol -= emittingVol * gJumboVolOffsetPercentage / 100; + m_sQueueSample.m_nVolume = ComputeVolume(emittingVol, SOUND_INTENSITY, m_sQueueSample.m_fDistance); + + if (m_sQueueSample.m_nVolume != 0) { + m_sQueueSample.m_nCounter = 1; + m_sQueueSample.m_nSampleIndex = SFX_JUMBO_TAXI; + m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_nReleasingVolumeModificator = 1; + m_sQueueSample.m_nFrequency = GetJumboTaxiFreq(); + m_sQueueSample.m_nLoopCount = 0; + m_sQueueSample.m_nEmittingVolume = emittingVol; + m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_fSpeedMultiplier = 4.0f; + m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY; + m_sQueueSample.m_bReleasingSoundFlag = false; + m_sQueueSample.m_nReleasingVolumeDivider = 4; + m_sQueueSample.m_bReverbFlag = true; + m_sQueueSample.m_bRequireReflection = false; + AddSampleToRequestedQueue(); + } + return true; +} + +bool +cAudioManager::SetupJumboWhineSound(uint8 emittingVol, int32 freq) +{ + const float SOUND_INTENSITY = 170.0f; + + if (m_sQueueSample.m_fDistance >= SOUND_INTENSITY) + return false; + + m_sQueueSample.m_nVolume = ComputeVolume(emittingVol, SOUND_INTENSITY, m_sQueueSample.m_fDistance); + + if (m_sQueueSample.m_nVolume != 0) { + m_sQueueSample.m_nCounter = 2; + m_sQueueSample.m_nSampleIndex = SFX_JUMBO_WHINE; + m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_nReleasingVolumeModificator = 1; + m_sQueueSample.m_nFrequency = freq; + m_sQueueSample.m_nLoopCount = 0; + m_sQueueSample.m_nEmittingVolume = emittingVol; + m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_fSpeedMultiplier = 4.0f; + m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY; + m_sQueueSample.m_bReleasingSoundFlag = false; + m_sQueueSample.m_nReleasingVolumeDivider = 4; + m_sQueueSample.m_bReverbFlag = true; + m_sQueueSample.m_bRequireReflection = false; + AddSampleToRequestedQueue(); + } + return true; +} + +bool +cAudioManager::SetupJumboEngineSound(uint8 vol, int32 freq) +{ + const float SOUND_INTENSITY = 180.0f; + if (m_sQueueSample.m_fDistance >= SOUND_INTENSITY) + return false; + + uint8 emittingVol = vol - gJumboVolOffsetPercentage / 100; + m_sQueueSample.m_nVolume = ComputeVolume(emittingVol, SOUND_INTENSITY, m_sQueueSample.m_fDistance); + if (m_sQueueSample.m_nVolume != 0) { + m_sQueueSample.m_nCounter = 3; + m_sQueueSample.m_nSampleIndex = SFX_JUMBO_ENGINE; + m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_nReleasingVolumeModificator = 1; + m_sQueueSample.m_nFrequency = freq; + m_sQueueSample.m_nLoopCount = 0; + m_sQueueSample.m_nEmittingVolume = emittingVol; + m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_fSpeedMultiplier = 4.0f; + m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY; + m_sQueueSample.m_bReleasingSoundFlag = false; + m_sQueueSample.m_nReleasingVolumeDivider = 4; + m_sQueueSample.m_bReverbFlag = true; + m_sQueueSample.m_bRequireReflection = false; + AddSampleToRequestedQueue(); + } + return true; +} + +bool +cAudioManager::SetupJumboFlySound(uint8 emittingVol) +{ + const float SOUND_INTENSITY = 440.0f; + if (m_sQueueSample.m_fDistance >= SOUND_INTENSITY) + return false; + + int32 vol = ComputeVolume(emittingVol, SOUND_INTENSITY, m_sQueueSample.m_fDistance); + m_sQueueSample.m_nVolume = vol; + if (m_sQueueSample.m_nVolume != 0) { + m_sQueueSample.m_nSampleIndex = SFX_JUMBO_DIST_FLY; + m_sQueueSample.m_nCounter = 0; + m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_nReleasingVolumeModificator = 1; + m_sQueueSample.m_nEmittingVolume = emittingVol; + m_sQueueSample.m_nLoopCount = 0; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_JUMBO_DIST_FLY); + m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY; + m_sQueueSample.m_bReleasingSoundFlag = false; + m_sQueueSample.m_fSpeedMultiplier = 4.0f; + m_sQueueSample.m_bReverbFlag = true; + m_sQueueSample.m_nReleasingVolumeDivider = 5; + m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex); + AddSampleToRequestedQueue(); + } + return true; +} + +bool +cAudioManager::SetupJumboRumbleSound(uint8 emittingVol) +{ + const float SOUND_INTENSITY = 240.0f; + if (m_sQueueSample.m_fDistance >= SOUND_INTENSITY) + return false; + + m_sQueueSample.m_nVolume = ComputeVolume(emittingVol, SOUND_INTENSITY, m_sQueueSample.m_fDistance); + + if (m_sQueueSample.m_nVolume != 0) { + m_sQueueSample.m_nCounter = 5; + m_sQueueSample.m_nSampleIndex = SFX_JUMBO_RUMBLE; + m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; + m_sQueueSample.m_bIs2D = true; + m_sQueueSample.m_nReleasingVolumeModificator = 1; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_JUMBO_RUMBLE); + m_sQueueSample.m_nLoopCount = 0; + m_sQueueSample.m_nEmittingVolume = emittingVol; + m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_fSpeedMultiplier = 4.0f; + m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY; + m_sQueueSample.m_bReleasingSoundFlag = false; + m_sQueueSample.m_nReleasingVolumeDivider = 12; + m_sQueueSample.m_nOffset = 0; + m_sQueueSample.m_bReverbFlag = true; + m_sQueueSample.m_bRequireReflection = false; + AddSampleToRequestedQueue(); + m_sQueueSample.m_nCounter = 6; + m_sQueueSample.m_nSampleIndex = SFX_JUMBO_RUMBLE; + m_sQueueSample.m_nFrequency += 200; + m_sQueueSample.m_nOffset = MAX_VOLUME; + AddSampleToRequestedQueue(); + } + return true; +} + +int32 +cAudioManager::GetJumboTaxiFreq() const +{ + return (60.833f * m_sQueueSample.m_fDistance) + 22050; +} + +#pragma endregion Some jumbo crap + +#pragma endregion All the vehicle audio code + +#pragma region PED AUDIO +void +cAudioManager::ProcessPed(CPhysical *ped) +{ + cPedParams params; + + params.m_pPed = nil; + params.m_bDistanceCalculated = false; + params.m_fDistance = 0.0f; + + m_sQueueSample.m_vecPos = ped->GetPosition(); + + // params.m_bDistanceCalculated = false; + params.m_pPed = (CPed *)ped; + params.m_fDistance = GetDistanceSquared(m_sQueueSample.m_vecPos); + ProcessPedOneShots(¶ms); +} + +void +cAudioManager::ProcessPedOneShots(cPedParams *params) +{ + uint8 emittingVol; + int32 sampleIndex; + + CPed *ped = params->m_pPed; + + bool stereo; + int16 sound; + bool noReflection; + CWeapon *weapon; + float maxDist = 0.f; // uninitialized variable + + static uint8 iSound = 21; + + weapon = params->m_pPed->GetWeapon(); + for (uint32 i = 0; i < m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_AudioEvents; i++) { + noReflection = false; + stereo = false; + m_sQueueSample.m_bRequireReflection = false; + sound = m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_awAudioEvent[i]; + switch (sound) { + case SOUND_STEP_START: + case SOUND_STEP_END: + if (!params->m_pPed->bIsLooking) { + emittingVol = m_anRandomTable[3] % 15 + 45; + if (FindPlayerPed() != m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_pEntity) + emittingVol /= 2; + maxDist = 400.f; + switch (params->m_pPed->m_nSurfaceTouched) { + case SURFACE_GRASS: + sampleIndex = m_anRandomTable[1] % 5 + SFX_FOOTSTEP_GRASS_1; + break; + case SURFACE_GRAVEL: + case SURFACE_MUD_DRY: + sampleIndex = m_anRandomTable[4] % 5 + SFX_FOOTSTEP_GRAVEL_1; + break; + case SURFACE_CAR: + case SURFACE_GARAGE_DOOR: + case SURFACE_CAR_PANEL: + case SURFACE_THICK_METAL_PLATE: + case SURFACE_SCAFFOLD_POLE: + case SURFACE_LAMP_POST: + case SURFACE_FIRE_HYDRANT: + case SURFACE_GIRDER: + case SURFACE_METAL_CHAIN_FENCE: + case SURFACE_CONTAINER: + case SURFACE_NEWS_VENDOR: + sampleIndex = m_anRandomTable[0] % 5 + SFX_FOOTSTEP_METAL_1; + break; + case SURFACE_SAND: + sampleIndex = (m_anRandomTable[4] & 3) + SFX_FOOTSTEP_SAND_1; + break; + case SURFACE_WATER: + sampleIndex = (m_anRandomTable[3] & 3) + SFX_FOOTSTEP_WATER_1; + break; + case SURFACE_WOOD_CRATES: + case SURFACE_WOOD_BENCH: + case SURFACE_WOOD_SOLID: + sampleIndex = m_anRandomTable[2] % 5 + SFX_FOOTSTEP_WOOD_1; + break; + case SURFACE_HEDGE: + sampleIndex = m_anRandomTable[2] % 5 + SFX_COL_VEG_1; + break; + default: + sampleIndex = m_anRandomTable[2] % 5 + SFX_FOOTSTEP_CONCRETE_1; + break; + } + m_sQueueSample.m_nSampleIndex = sampleIndex; + m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; + m_sQueueSample.m_nCounter = m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_awAudioEvent[i] - 28; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_nFrequency += RandomDisplacement(m_sQueueSample.m_nFrequency / 17); + switch (params->m_pPed->m_nMoveState) { + case PEDMOVE_WALK: + emittingVol /= 4; + m_sQueueSample.m_nFrequency = 9 * m_sQueueSample.m_nFrequency / 10; + break; + case PEDMOVE_RUN: + emittingVol /= 2; + m_sQueueSample.m_nFrequency = 11 * m_sQueueSample.m_nFrequency / 10; + break; + case PEDMOVE_SPRINT: + m_sQueueSample.m_nFrequency = 12 * m_sQueueSample.m_nFrequency / 10; + break; + default: + break; + } + m_sQueueSample.m_nReleasingVolumeModificator = 5; + m_sQueueSample.m_fSpeedMultiplier = 0.0f; + m_sQueueSample.m_fSoundIntensity = 20.0f; + m_sQueueSample.m_nLoopCount = 1; + m_sQueueSample.m_nLoopStart = 0; + m_sQueueSample.m_nLoopEnd = -1; + m_sQueueSample.m_nEmittingVolume = emittingVol; + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_bReleasingSoundFlag = true; + m_sQueueSample.m_bRequireReflection = true; + } + break; + case SOUND_FALL_LAND: + case SOUND_FALL_COLLAPSE: + if (!ped->bIsLooking) { + maxDist = SQR(30); + emittingVol = m_anRandomTable[3] % 20 + 80; + if (ped->m_nSurfaceTouched == SURFACE_WATER) { + m_sQueueSample.m_nSampleIndex = (m_anRandomTable[3] & 3) + SFX_FOOTSTEP_WATER_1; + } else if (sound == SOUND_FALL_LAND) { + m_sQueueSample.m_nSampleIndex = SFX_BODY_LAND; + } else { + m_sQueueSample.m_nSampleIndex = SFX_BODY_LAND_AND_FALL; + } + m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; + m_sQueueSample.m_nCounter = 1; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_nFrequency += RandomDisplacement(m_sQueueSample.m_nFrequency / 17); + m_sQueueSample.m_nReleasingVolumeModificator = 2; + m_sQueueSample.m_fSpeedMultiplier = 0.0f; + m_sQueueSample.m_fSoundIntensity = 30.0f; + m_sQueueSample.m_nLoopCount = 1; + m_sQueueSample.m_nLoopStart = 0; + m_sQueueSample.m_nLoopEnd = -1; + m_sQueueSample.m_nEmittingVolume = emittingVol; + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_bReleasingSoundFlag = true; + m_sQueueSample.m_bRequireReflection = true; + } + break; + case SOUND_FIGHT_PUNCH_33: + m_sQueueSample.m_nSampleIndex = SFX_FIGHT_1; + m_sQueueSample.m_nFrequency = 18000; + m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; + m_sQueueSample.m_nCounter = iSound; + stereo = true; + ++iSound; + m_sQueueSample.m_nReleasingVolumeModificator = 3; + m_sQueueSample.m_fSpeedMultiplier = 0.0f; + m_sQueueSample.m_fSoundIntensity = 30.0f; + maxDist = SQR(30); + m_sQueueSample.m_nLoopCount = 1; + m_sQueueSample.m_nLoopStart = 0; + emittingVol = m_anRandomTable[3] % 26 + 100; + m_sQueueSample.m_nLoopEnd = -1; + m_sQueueSample.m_nEmittingVolume = emittingVol; + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_bReleasingSoundFlag = true; + m_sQueueSample.m_bRequireReflection = true; + break; + case SOUND_FIGHT_KICK_34: + m_sQueueSample.m_nSampleIndex = SFX_FIGHT_1; + m_sQueueSample.m_nFrequency = 16500; + m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; + m_sQueueSample.m_nCounter = iSound; + stereo = true; + ++iSound; + m_sQueueSample.m_nReleasingVolumeModificator = 3; + m_sQueueSample.m_fSpeedMultiplier = 0.0f; + m_sQueueSample.m_fSoundIntensity = 30.0f; + maxDist = SQR(30); + m_sQueueSample.m_nLoopCount = 1; + m_sQueueSample.m_nLoopStart = 0; + emittingVol = m_anRandomTable[3] % 26 + 100; + m_sQueueSample.m_nLoopEnd = -1; + m_sQueueSample.m_nEmittingVolume = emittingVol; + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_bReleasingSoundFlag = true; + m_sQueueSample.m_bRequireReflection = true; + break; + case SOUND_FIGHT_HEADBUTT_35: + m_sQueueSample.m_nSampleIndex = SFX_FIGHT_1; + m_sQueueSample.m_nFrequency = 20000; + m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; + m_sQueueSample.m_nCounter = iSound; + stereo = true; + ++iSound; + m_sQueueSample.m_nReleasingVolumeModificator = 3; + m_sQueueSample.m_fSpeedMultiplier = 0.0f; + m_sQueueSample.m_fSoundIntensity = 30.0f; + maxDist = SQR(30); + m_sQueueSample.m_nLoopCount = 1; + m_sQueueSample.m_nLoopStart = 0; + emittingVol = m_anRandomTable[3] % 26 + 100; + m_sQueueSample.m_nLoopEnd = -1; + m_sQueueSample.m_nEmittingVolume = emittingVol; + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_bReleasingSoundFlag = true; + m_sQueueSample.m_bRequireReflection = true; + break; + case SOUND_FIGHT_PUNCH_36: + m_sQueueSample.m_nSampleIndex = SFX_FIGHT_2; + m_sQueueSample.m_nFrequency = 18000; + m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; + m_sQueueSample.m_nCounter = iSound; + stereo = true; + ++iSound; + m_sQueueSample.m_nReleasingVolumeModificator = 3; + m_sQueueSample.m_fSpeedMultiplier = 0.0f; + m_sQueueSample.m_fSoundIntensity = 30.0f; + maxDist = SQR(30); + m_sQueueSample.m_nLoopCount = 1; + m_sQueueSample.m_nLoopStart = 0; + emittingVol = m_anRandomTable[3] % 26 + 100; + m_sQueueSample.m_nLoopEnd = -1; + m_sQueueSample.m_nEmittingVolume = emittingVol; + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_bReleasingSoundFlag = true; + m_sQueueSample.m_bRequireReflection = true; + break; + case SOUND_FIGHT_PUNCH_37: + m_sQueueSample.m_nSampleIndex = SFX_FIGHT_2; + m_sQueueSample.m_nFrequency = 16500; + m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; + m_sQueueSample.m_nCounter = iSound; + stereo = true; + ++iSound; + m_sQueueSample.m_nReleasingVolumeModificator = 3; + m_sQueueSample.m_fSpeedMultiplier = 0.0f; + m_sQueueSample.m_fSoundIntensity = 30.0f; + maxDist = SQR(30); + m_sQueueSample.m_nLoopCount = 1; + m_sQueueSample.m_nLoopStart = 0; + emittingVol = m_anRandomTable[3] % 26 + 100; + m_sQueueSample.m_nLoopEnd = -1; + m_sQueueSample.m_nEmittingVolume = emittingVol; + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_bReleasingSoundFlag = true; + m_sQueueSample.m_bRequireReflection = true; + break; + case SOUND_FIGHT_CLOSE_PUNCH_38: + m_sQueueSample.m_nSampleIndex = SFX_FIGHT_2; + m_sQueueSample.m_nFrequency = 20000; + m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; + m_sQueueSample.m_nCounter = iSound; + stereo = true; + ++iSound; + m_sQueueSample.m_nReleasingVolumeModificator = 3; + m_sQueueSample.m_fSpeedMultiplier = 0.0f; + m_sQueueSample.m_fSoundIntensity = 30.0f; + maxDist = SQR(30); + m_sQueueSample.m_nLoopCount = 1; + m_sQueueSample.m_nLoopStart = 0; + emittingVol = m_anRandomTable[3] % 26 + 100; + m_sQueueSample.m_nLoopEnd = -1; + m_sQueueSample.m_nEmittingVolume = emittingVol; + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_bReleasingSoundFlag = true; + m_sQueueSample.m_bRequireReflection = true; + break; + case SOUND_FIGHT_PUNCH_39: + m_sQueueSample.m_nSampleIndex = SFX_FIGHT_4; + m_sQueueSample.m_nFrequency = 18000; + m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; + m_sQueueSample.m_nCounter = iSound; + stereo = true; + ++iSound; + m_sQueueSample.m_nReleasingVolumeModificator = 3; + m_sQueueSample.m_fSpeedMultiplier = 0.0f; + m_sQueueSample.m_fSoundIntensity = 30.0f; + maxDist = SQR(30); + m_sQueueSample.m_nLoopCount = 1; + m_sQueueSample.m_nLoopStart = 0; + emittingVol = m_anRandomTable[3] % 26 + 100; + m_sQueueSample.m_nLoopEnd = -1; + m_sQueueSample.m_nEmittingVolume = emittingVol; + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_bReleasingSoundFlag = true; + m_sQueueSample.m_bRequireReflection = true; + break; + case SOUND_FIGHT_PUNCH_OR_KICK_BELOW_40: + m_sQueueSample.m_nSampleIndex = SFX_FIGHT_4; + m_sQueueSample.m_nFrequency = 16500; + m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; + m_sQueueSample.m_nCounter = iSound; + stereo = true; + ++iSound; + m_sQueueSample.m_nReleasingVolumeModificator = 3; + m_sQueueSample.m_fSpeedMultiplier = 0.0f; + m_sQueueSample.m_fSoundIntensity = 30.0f; + maxDist = SQR(30); + m_sQueueSample.m_nLoopCount = 1; + m_sQueueSample.m_nLoopStart = 0; + emittingVol = m_anRandomTable[3] % 26 + 100; + m_sQueueSample.m_nLoopEnd = -1; + m_sQueueSample.m_nEmittingVolume = emittingVol; + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_bReleasingSoundFlag = true; + m_sQueueSample.m_bRequireReflection = true; + break; + case SOUND_FIGHT_PUNCH_41: + m_sQueueSample.m_nSampleIndex = SFX_FIGHT_4; + m_sQueueSample.m_nFrequency = 20000; + m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; + m_sQueueSample.m_nCounter = iSound; + stereo = true; + ++iSound; + m_sQueueSample.m_nReleasingVolumeModificator = 3; + m_sQueueSample.m_fSpeedMultiplier = 0.0f; + m_sQueueSample.m_fSoundIntensity = 30.0f; + maxDist = SQR(30); + m_sQueueSample.m_nLoopCount = 1; + m_sQueueSample.m_nLoopStart = 0; + emittingVol = m_anRandomTable[3] % 26 + 100; + m_sQueueSample.m_nLoopEnd = -1; + m_sQueueSample.m_nEmittingVolume = emittingVol; + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_bReleasingSoundFlag = true; + m_sQueueSample.m_bRequireReflection = true; + break; + case SOUND_FIGHT_PUNCH_FROM_BEHIND_42: + m_sQueueSample.m_nSampleIndex = SFX_FIGHT_5; + m_sQueueSample.m_nFrequency = 18000; + m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; + m_sQueueSample.m_nCounter = iSound; + stereo = true; + ++iSound; + m_sQueueSample.m_nReleasingVolumeModificator = 3; + m_sQueueSample.m_fSpeedMultiplier = 0.0f; + m_sQueueSample.m_fSoundIntensity = 30.0f; + maxDist = SQR(30); + m_sQueueSample.m_nLoopCount = 1; + m_sQueueSample.m_nLoopStart = 0; + emittingVol = m_anRandomTable[3] % 26 + 100; + m_sQueueSample.m_nLoopEnd = -1; + m_sQueueSample.m_nEmittingVolume = emittingVol; + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_bReleasingSoundFlag = true; + m_sQueueSample.m_bRequireReflection = true; + break; + case SOUND_FIGHT_KNEE_OR_KICK_43: + m_sQueueSample.m_nSampleIndex = SFX_FIGHT_5; + m_sQueueSample.m_nFrequency = 16500; + m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; + m_sQueueSample.m_nCounter = iSound; + stereo = true; + ++iSound; + m_sQueueSample.m_nReleasingVolumeModificator = 3; + m_sQueueSample.m_fSpeedMultiplier = 0.0f; + m_sQueueSample.m_fSoundIntensity = 30.0f; + maxDist = SQR(30); + m_sQueueSample.m_nLoopCount = 1; + m_sQueueSample.m_nLoopStart = 0; + emittingVol = m_anRandomTable[3] % 26 + 100; + m_sQueueSample.m_nLoopEnd = -1; + m_sQueueSample.m_nEmittingVolume = emittingVol; + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_bReleasingSoundFlag = true; + m_sQueueSample.m_bRequireReflection = true; + break; + case SOUND_FIGHT_KICK_44: + m_sQueueSample.m_nSampleIndex = SFX_FIGHT_5; + m_sQueueSample.m_nFrequency = 20000; + m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; + m_sQueueSample.m_nCounter = iSound; + stereo = true; + ++iSound; + m_sQueueSample.m_nReleasingVolumeModificator = 3; + m_sQueueSample.m_fSpeedMultiplier = 0.0f; + m_sQueueSample.m_fSoundIntensity = 30.0f; + maxDist = SQR(30); + m_sQueueSample.m_nLoopCount = 1; + m_sQueueSample.m_nLoopStart = 0; + emittingVol = m_anRandomTable[3] % 26 + 100; + m_sQueueSample.m_nLoopEnd = -1; + m_sQueueSample.m_nEmittingVolume = emittingVol; + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_bReleasingSoundFlag = true; + m_sQueueSample.m_bRequireReflection = true; + break; + case SOUND_WEAPON_BAT_ATTACK: + m_sQueueSample.m_nSampleIndex = SFX_BAT_HIT_LEFT; + m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; + m_sQueueSample.m_nCounter = iSound++; + stereo = true; + m_sQueueSample.m_nFrequency = RandomDisplacement(2000) + 22000; + m_sQueueSample.m_nReleasingVolumeModificator = 3; + m_sQueueSample.m_fSpeedMultiplier = 0.0f; + m_sQueueSample.m_fSoundIntensity = 30.0f; + maxDist = SQR(30); + m_sQueueSample.m_nLoopCount = 1; + m_sQueueSample.m_nLoopStart = 0; + m_sQueueSample.m_nLoopEnd = -1; + emittingVol = m_anRandomTable[2] % 20 + 100; + m_sQueueSample.m_nEmittingVolume = emittingVol; + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_bReleasingSoundFlag = true; + if (m_bDynamicAcousticModelingStatus) + m_sQueueSample.m_bRequireReflection = true; + else + noReflection = true; + break; + case SOUND_WEAPON_SHOT_FIRED: + weapon = ped->GetWeapon(); + switch (weapon->m_eWeaponType) { + case WEAPONTYPE_COLT45: + m_sQueueSample.m_nSampleIndex = SFX_COLT45_LEFT; + m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; + m_sQueueSample.m_nCounter = iSound++; + stereo = true; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_COLT45_LEFT); + m_sQueueSample.m_nFrequency += RandomDisplacement(m_sQueueSample.m_nFrequency / 32); + m_sQueueSample.m_nReleasingVolumeModificator = 3; + m_sQueueSample.m_fSpeedMultiplier = 0.0f; + m_sQueueSample.m_fSoundIntensity = 50.0f; + maxDist = SQR(50); + m_sQueueSample.m_nLoopCount = 1; + m_sQueueSample.m_nLoopStart = 0; + m_sQueueSample.m_nLoopEnd = -1; + emittingVol = m_anRandomTable[1] % 10 + 90; + m_sQueueSample.m_nEmittingVolume = emittingVol; + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_bReleasingSoundFlag = true; + if (m_bDynamicAcousticModelingStatus) + m_sQueueSample.m_bRequireReflection = true; + else + noReflection = true; + break; + case WEAPONTYPE_UZI: + m_sQueueSample.m_nSampleIndex = SFX_UZI_LEFT; + m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; + m_sQueueSample.m_nCounter = iSound++; + stereo = true; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_UZI_LEFT); + m_sQueueSample.m_nFrequency += RandomDisplacement(m_sQueueSample.m_nFrequency / 32); + m_sQueueSample.m_nReleasingVolumeModificator = 3; + m_sQueueSample.m_fSpeedMultiplier = 0.0f; + m_sQueueSample.m_fSoundIntensity = 80.0f; + maxDist = SQR(80); + m_sQueueSample.m_nLoopCount = 1; + m_sQueueSample.m_nLoopStart = 0; + emittingVol = m_anRandomTable[3] % 15 + 70; + m_sQueueSample.m_nLoopEnd = -1; + m_sQueueSample.m_nEmittingVolume = emittingVol; + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_bReleasingSoundFlag = true; + break; + case WEAPONTYPE_SHOTGUN: + m_sQueueSample.m_nSampleIndex = SFX_SHOTGUN_LEFT; + m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; + m_sQueueSample.m_nCounter = iSound++; + stereo = true; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_SHOTGUN_LEFT); + m_sQueueSample.m_nFrequency += RandomDisplacement(m_sQueueSample.m_nFrequency / 32); + m_sQueueSample.m_nReleasingVolumeModificator = 3; + m_sQueueSample.m_fSpeedMultiplier = 0.0f; + m_sQueueSample.m_fSoundIntensity = 60.0f; + maxDist = SQR(60); + m_sQueueSample.m_nLoopCount = 1; + m_sQueueSample.m_nLoopStart = 0; + m_sQueueSample.m_nLoopEnd = -1; + emittingVol = m_anRandomTable[2] % 10 + 100; + m_sQueueSample.m_nEmittingVolume = emittingVol; + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_bReleasingSoundFlag = true; + if (m_bDynamicAcousticModelingStatus) + m_sQueueSample.m_bRequireReflection = true; + else + noReflection = true; + break; + case WEAPONTYPE_RUGER: + m_sQueueSample.m_nSampleIndex = SFX_AK47_LEFT; + m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; + m_sQueueSample.m_nCounter = iSound++; + stereo = true; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_AK47_LEFT); + m_sQueueSample.m_nFrequency += RandomDisplacement(m_sQueueSample.m_nFrequency / 32); + m_sQueueSample.m_nReleasingVolumeModificator = 3; + m_sQueueSample.m_fSpeedMultiplier = 0.0f; + m_sQueueSample.m_fSoundIntensity = 80.0f; + maxDist = SQR(80); + m_sQueueSample.m_nLoopCount = 1; + m_sQueueSample.m_nLoopStart = 0; + emittingVol = m_anRandomTable[1] % 15 + 70; + m_sQueueSample.m_nLoopEnd = -1; + m_sQueueSample.m_nEmittingVolume = emittingVol; + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_bReleasingSoundFlag = true; + break; + case WEAPONTYPE_M4: + m_sQueueSample.m_nSampleIndex = SFX_M16_LEFT; + m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; + m_sQueueSample.m_nCounter = iSound++; + stereo = true; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_M16_LEFT); + m_sQueueSample.m_nFrequency += RandomDisplacement(m_sQueueSample.m_nFrequency / 32); + m_sQueueSample.m_nReleasingVolumeModificator = 3; + m_sQueueSample.m_fSpeedMultiplier = 0.0f; + m_sQueueSample.m_fSoundIntensity = 80.0f; + maxDist = SQR(80); + m_sQueueSample.m_nLoopCount = 1; + m_sQueueSample.m_nLoopStart = 0; + emittingVol = m_anRandomTable[4] % 15 + 70; + m_sQueueSample.m_nLoopEnd = -1; + m_sQueueSample.m_nEmittingVolume = emittingVol; + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_bReleasingSoundFlag = true; + break; + case WEAPONTYPE_SNIPERRIFLE: + m_sQueueSample.m_nSampleIndex = SFX_SNIPER_LEFT; + m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; + m_sQueueSample.m_nCounter = iSound++; + stereo = true; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_SNIPER_LEFT); + m_sQueueSample.m_nFrequency += RandomDisplacement(m_sQueueSample.m_nFrequency / 32); + m_sQueueSample.m_nReleasingVolumeModificator = 3; + m_sQueueSample.m_fSpeedMultiplier = 0.0f; + m_sQueueSample.m_fSoundIntensity = 60.0f; + maxDist = SQR(60); + m_sQueueSample.m_nLoopCount = 1; + m_sQueueSample.m_nLoopStart = 0; + m_sQueueSample.m_nLoopEnd = -1; + emittingVol = m_anRandomTable[4] % 10 + 110; + m_sQueueSample.m_nEmittingVolume = emittingVol; + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_bReleasingSoundFlag = true; + if (m_bDynamicAcousticModelingStatus) + m_sQueueSample.m_bRequireReflection = true; + else + noReflection = true; + break; + case WEAPONTYPE_ROCKETLAUNCHER: + m_sQueueSample.m_nSampleIndex = SFX_ROCKET_LEFT; + m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; + m_sQueueSample.m_nCounter = iSound++; + stereo = true; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_ROCKET_LEFT); + m_sQueueSample.m_nFrequency += RandomDisplacement(m_sQueueSample.m_nFrequency / 32); + m_sQueueSample.m_nReleasingVolumeModificator = 1; + m_sQueueSample.m_fSpeedMultiplier = 0.0f; + m_sQueueSample.m_fSoundIntensity = 90.0f; + maxDist = SQR(90); + m_sQueueSample.m_nLoopCount = 1; + m_sQueueSample.m_nLoopStart = 0; + m_sQueueSample.m_nLoopEnd = -1; + emittingVol = m_anRandomTable[0] % 20 + 80; + m_sQueueSample.m_nEmittingVolume = emittingVol; + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_bReleasingSoundFlag = true; + if (m_bDynamicAcousticModelingStatus) + m_sQueueSample.m_bRequireReflection = true; + else + noReflection = true; + break; + case WEAPONTYPE_FLAMETHROWER: + m_sQueueSample.m_nSampleIndex = SFX_FLAMETHROWER_LEFT; + m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; + m_sQueueSample.m_nCounter = 9; + emittingVol = 90; + m_sQueueSample.m_nFrequency = (10 * m_sQueueSample.m_nEntityIndex & 2047) + SampleManager.GetSampleBaseFrequency(SFX_FLAMETHROWER_LEFT); + m_sQueueSample.m_nReleasingVolumeModificator = 3; + m_sQueueSample.m_fSpeedMultiplier = 4.0f; + m_sQueueSample.m_fSoundIntensity = 60.0f; + maxDist = SQR(60); + m_sQueueSample.m_nLoopCount = 0; + m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_nEmittingVolume = 90; + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_bReleasingSoundFlag = false; + m_sQueueSample.m_nReleasingVolumeDivider = 6; + if (m_bDynamicAcousticModelingStatus) + m_sQueueSample.m_bRequireReflection = true; + else + noReflection = true; + break; + default: + continue; + } + + break; + case SOUND_WEAPON_RELOAD: + weapon = &ped->m_weapons[ped->m_currentWeapon]; + switch (weapon->m_eWeaponType) { + case WEAPONTYPE_COLT45: + m_sQueueSample.m_nSampleIndex = SFX_PISTOL_RELOAD; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_PISTOL_RELOAD) + RandomDisplacement(300); + break; + case WEAPONTYPE_UZI: + m_sQueueSample.m_nSampleIndex = SFX_M16_RELOAD; + m_sQueueSample.m_nFrequency = 39243; + break; + case WEAPONTYPE_SHOTGUN: + m_sQueueSample.m_nSampleIndex = SFX_AK47_RELOAD; + m_sQueueSample.m_nFrequency = 30290; + break; + case WEAPONTYPE_RUGER: + m_sQueueSample.m_nSampleIndex = SFX_AK47_RELOAD; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_AK47_RELOAD); + break; + case WEAPONTYPE_M4: + m_sQueueSample.m_nSampleIndex = SFX_M16_RELOAD; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_M16_RELOAD); + break; + case WEAPONTYPE_SNIPERRIFLE: + m_sQueueSample.m_nSampleIndex = SFX_RIFLE_RELOAD; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_RIFLE_RELOAD); + break; + case WEAPONTYPE_ROCKETLAUNCHER: + m_sQueueSample.m_nSampleIndex = SFX_ROCKET_RELOAD; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_ROCKET_RELOAD); + break; + default: + continue; + } + emittingVol = 75; + m_sQueueSample.m_nCounter = iSound++; + stereo = true; + m_sQueueSample.m_nFrequency += RandomDisplacement(300); + m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; + m_sQueueSample.m_nReleasingVolumeModificator = 5; + m_sQueueSample.m_fSpeedMultiplier = 0.0f; + m_sQueueSample.m_fSoundIntensity = 30.0f; + maxDist = SQR(30); + m_sQueueSample.m_nLoopCount = 1; + m_sQueueSample.m_nLoopStart = 0; + m_sQueueSample.m_nLoopEnd = -1; + m_sQueueSample.m_nEmittingVolume = 75; + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_bReleasingSoundFlag = true; + m_sQueueSample.m_bRequireReflection = true; + break; + case SOUND_WEAPON_AK47_BULLET_ECHO: + case SOUND_WEAPON_UZI_BULLET_ECHO: + case SOUND_WEAPON_M16_BULLET_ECHO: + m_sQueueSample.m_nSampleIndex = SFX_UZI_END_LEFT; + m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; + m_sQueueSample.m_nCounter = iSound++; + stereo = true; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_UZI_END_LEFT); + m_sQueueSample.m_nFrequency += RandomDisplacement(m_sQueueSample.m_nFrequency / 16); + m_sQueueSample.m_nReleasingVolumeModificator = 3; + m_sQueueSample.m_fSpeedMultiplier = 0.0f; + m_sQueueSample.m_fSoundIntensity = 80.0f; + maxDist = SQR(80); + m_sQueueSample.m_nLoopCount = 1; + m_sQueueSample.m_nLoopStart = 0; + m_sQueueSample.m_nLoopEnd = -1; + emittingVol = m_anRandomTable[4] % 10 + 40; + m_sQueueSample.m_nEmittingVolume = emittingVol; + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_bReleasingSoundFlag = true; + if (m_bDynamicAcousticModelingStatus) + m_sQueueSample.m_bRequireReflection = true; + else + noReflection = true; + break; + case SOUND_WEAPON_FLAMETHROWER_FIRE: + m_sQueueSample.m_nSampleIndex = SFX_FLAMETHROWER_START_LEFT; + m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; + m_sQueueSample.m_nCounter = iSound++; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_FLAMETHROWER_START_LEFT); + m_sQueueSample.m_nFrequency += RandomDisplacement(m_sQueueSample.m_nFrequency / 16); + m_sQueueSample.m_nReleasingVolumeModificator = 3; + m_sQueueSample.m_fSpeedMultiplier = 4.0f; + m_sQueueSample.m_fSoundIntensity = 60.0f; + maxDist = SQR(60); + m_sQueueSample.m_nLoopCount = 1; + m_sQueueSample.m_nLoopStart = 0; + m_sQueueSample.m_nLoopEnd = -1; + emittingVol = 70; + m_sQueueSample.m_nEmittingVolume = 70; + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_bReleasingSoundFlag = true; + break; + case SOUND_WEAPON_HIT_PED: + m_sQueueSample.m_nSampleIndex = SFX_BULLET_PED; + m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; + m_sQueueSample.m_nCounter = iSound++; + stereo = true; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_BULLET_PED); + m_sQueueSample.m_nFrequency += RandomDisplacement(m_sQueueSample.m_nFrequency / 8); + m_sQueueSample.m_nReleasingVolumeModificator = 7; + m_sQueueSample.m_fSpeedMultiplier = 0.0f; + m_sQueueSample.m_fSoundIntensity = 30.0f; + maxDist = SQR(30); + m_sQueueSample.m_nLoopCount = 1; + m_sQueueSample.m_nLoopStart = 0; + emittingVol = m_anRandomTable[0] % 20 + 90; + m_sQueueSample.m_nLoopEnd = -1; + m_sQueueSample.m_nEmittingVolume = emittingVol; + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_bReleasingSoundFlag = true; + break; + case SOUND_SPLASH: + m_sQueueSample.m_nSampleIndex = SFX_SPLASH_1; + m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; + m_sQueueSample.m_nCounter = iSound++; + stereo = true; + m_sQueueSample.m_nFrequency = RandomDisplacement(1400) + 20000; + m_sQueueSample.m_nReleasingVolumeModificator = 1; + m_sQueueSample.m_fSpeedMultiplier = 0.0f; + m_sQueueSample.m_fSoundIntensity = 40.0f; + maxDist = SQR(40); + m_sQueueSample.m_nLoopCount = 1; + m_sQueueSample.m_nLoopStart = 0; + emittingVol = m_anRandomTable[2] % 30 + 70; + m_sQueueSample.m_nLoopEnd = -1; + m_sQueueSample.m_nEmittingVolume = emittingVol; + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_bReleasingSoundFlag = true; + m_sQueueSample.m_bRequireReflection = true; + break; + default: + SetupPedComments(params, sound); + continue; + } + + if (stereo && iSound > 60) + iSound = 21; + if (params->m_fDistance < maxDist) { + CalculateDistance(params->m_bDistanceCalculated, params->m_fDistance); + m_sQueueSample.m_nVolume = ComputeVolume(emittingVol, m_sQueueSample.m_fSoundIntensity, m_sQueueSample.m_fDistance); + if (m_sQueueSample.m_nVolume != 0) { + if (noReflection) { + if (m_sQueueSample.m_fDistance < 0.2f * m_sQueueSample.m_fSoundIntensity) { + m_sQueueSample.m_bIs2D = true; + m_sQueueSample.m_nOffset = 0; + } else { + noReflection = false; + } + } + m_sQueueSample.m_bReverbFlag = true; + AddSampleToRequestedQueue(); + if (noReflection) { + m_sQueueSample.m_nOffset = 127; + ++m_sQueueSample.m_nSampleIndex; + if (m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_awAudioEvent[i] != SOUND_WEAPON_SHOT_FIRED || + weapon->m_eWeaponType != WEAPONTYPE_FLAMETHROWER) { + m_sQueueSample.m_nCounter = iSound++; + if (iSound > 60) + iSound = 21; + } else { + ++m_sQueueSample.m_nCounter; + } + AddSampleToRequestedQueue(); + } + } + } + } +} + +void +cAudioManager::SetupPedComments(cPedParams *params, uint32 sound) +{ + CPed *ped = params->m_pPed; + uint8 emittingVol; + float soundIntensity; + tPedComment pedComment; + + if (ped != nil) { + switch (sound) { + case SOUND_AMMUNATION_WELCOME_1: + pedComment.m_nSampleIndex = SFX_AMMU_D; + break; + case SOUND_AMMUNATION_WELCOME_2: + pedComment.m_nSampleIndex = SFX_AMMU_E; + break; + case SOUND_AMMUNATION_WELCOME_3: + pedComment.m_nSampleIndex = SFX_AMMU_F; + break; + default: + pedComment.m_nSampleIndex = GetPedCommentSfx(ped, sound); + if (pedComment.m_nSampleIndex == NO_SAMPLE) + return; + break; + } + + soundIntensity = 50.0f; + } else { + switch (sound) { + case SOUND_PED_HELI_PLAYER_FOUND: + soundIntensity = 400.0f; + pedComment.m_nSampleIndex = GetRandomNumberInRange(m_sQueueSample.m_nEntityIndex % 4, SFX_POLICE_HELI_1, SFX_POLICE_HELI_29); + break; + case SOUND_PED_BODYCAST_HIT: + if (CTimer::GetTimeInMilliseconds() <= gNextCryTime) + return; + soundIntensity = 50.0f; + gNextCryTime = CTimer::GetTimeInMilliseconds() + 500; + pedComment.m_nSampleIndex = GetRandomNumberInRange(m_sQueueSample.m_nEntityIndex % 4, SFX_PLASTER_BLOKE_1, SFX_PLASTER_BLOKE_4); + break; + case SOUND_INJURED_PED_MALE_OUCH: + case SOUND_INJURED_PED_MALE_PRISON: + soundIntensity = 50.0f; + pedComment.m_nSampleIndex = GetRandomNumberInRange(m_sQueueSample.m_nEntityIndex % 4, SFX_GENERIC_MALE_GRUNT_1, SFX_GENERIC_MALE_GRUNT_15); + break; + case SOUND_INJURED_PED_FEMALE: + soundIntensity = 50.0f; + pedComment.m_nSampleIndex = GetRandomNumberInRange(m_sQueueSample.m_nEntityIndex % 4, SFX_GENERIC_FEMALE_GRUNT_1, SFX_GENERIC_FEMALE_GRUNT_11); + break; + default: + return; + } + } + + if (params->m_fDistance < SQR(soundIntensity)) { + CalculateDistance(params->m_bDistanceCalculated, params->m_fDistance); + if (sound != SOUND_PAGER) { + switch (sound) { + case SOUND_AMMUNATION_WELCOME_1: + case SOUND_AMMUNATION_WELCOME_2: + case SOUND_AMMUNATION_WELCOME_3: + emittingVol = MAX_VOLUME; + break; + default: + if (CWorld::GetIsLineOfSightClear(TheCamera.GetPosition(), m_sQueueSample.m_vecPos, true, false, false, false, false, false)) + emittingVol = MAX_VOLUME; + else + emittingVol = 31; + break; + } + m_sQueueSample.m_nVolume = ComputeVolume(emittingVol, soundIntensity, m_sQueueSample.m_fDistance); + pedComment.m_nProcess = 10; + if (m_sQueueSample.m_nVolume != 0) { + pedComment.m_nEntityIndex = m_sQueueSample.m_nEntityIndex; + pedComment.m_vecPos = m_sQueueSample.m_vecPos; + pedComment.m_fDistance = m_sQueueSample.m_fDistance; + pedComment.m_bVolume = m_sQueueSample.m_nVolume; + m_sPedComments.Add(&pedComment); + } + } + } +} + +int32 +cAudioManager::GetPedCommentSfx(CPed *ped, int32 sound) +{ + //if (ped->IsPlayer()) + // return GetPlayerTalkSfx(sound); + + // TODO(Miami): ped comments + + return NO_SAMPLE; +} + +void +cAudioManager::GetPhrase(uint32 *phrase, uint32 *prevPhrase, uint32 sample, uint32 maxOffset) const +{ + *phrase = sample + m_anRandomTable[m_sQueueSample.m_nEntityIndex & 3] % maxOffset; + + // check if the same sfx like last time, if yes, then try use next one, + // if exceeded range, then choose first available sample + if (*phrase == *prevPhrase && ++*phrase >= sample + maxOffset) + *phrase = sample; + *prevPhrase = *phrase; +} + +#pragma region PED_COMMENTS +// TODO: all the ped comment funcs should follow here +void +cPedComments::Add(tPedComment *com) +{ + uint8 index; + + if (m_nCommentsInBank[m_nActiveBank] >= NUM_PED_COMMENTS_SLOTS) { + index = m_nIndexMap[m_nActiveBank][NUM_PED_COMMENTS_SLOTS - 1]; + if (m_asPedComments[m_nActiveBank][index].m_bVolume > com->m_bVolume) + return; + } else { + index = m_nCommentsInBank[m_nActiveBank]++; + } + + m_asPedComments[m_nActiveBank][index] = *com; + + uint32 i = 0; + if (index != 0) { + for (i = 0; i < index; i++) { + if (m_asPedComments[m_nActiveBank][m_nIndexMap[m_nActiveBank][i]].m_bVolume < m_asPedComments[m_nActiveBank][index].m_bVolume) { + break; + } + } + + if (i < index) + memmove(&m_nIndexMap[m_nActiveBank][i + 1], &m_nIndexMap[m_nActiveBank][i], NUM_PED_COMMENTS_SLOTS - 1 - i); + } + + m_nIndexMap[m_nActiveBank][i] = index; +} + +void +cPedComments::Process() +{ + int sampleIndex; + uint8 actualUsedBank; + tPedComment *comment; + + if (AudioManager.m_nUserPause != 0) return; + + if (m_nCommentsInBank[m_nActiveBank]) { + sampleIndex = m_asPedComments[m_nActiveBank][m_nIndexMap[m_nActiveBank][0]].m_nSampleIndex; + if (!SampleManager.IsPedCommentLoaded(sampleIndex)) + SampleManager.LoadPedComment(sampleIndex); + + AudioManager.m_sQueueSample.m_nEntityIndex = m_asPedComments[m_nActiveBank][m_nIndexMap[m_nActiveBank][0]].m_nEntityIndex; + AudioManager.m_sQueueSample.m_nCounter = 0; + AudioManager.m_sQueueSample.m_nSampleIndex = sampleIndex; + AudioManager.m_sQueueSample.m_nBankIndex = SAMPLEBANK_PED; + AudioManager.m_sQueueSample.m_nReleasingVolumeModificator = 3; + AudioManager.m_sQueueSample.m_nVolume = m_asPedComments[m_nActiveBank][m_nIndexMap[m_nActiveBank][0]].m_bVolume; + AudioManager.m_sQueueSample.m_fDistance = m_asPedComments[m_nActiveBank][m_nIndexMap[m_nActiveBank][0]].m_fDistance; + AudioManager.m_sQueueSample.m_nLoopCount = 1; + AudioManager.m_sQueueSample.m_nLoopStart = 0; + AudioManager.m_sQueueSample.m_nLoopEnd = -1; + AudioManager.m_sQueueSample.m_nEmittingVolume = MAX_VOLUME; + AudioManager.m_sQueueSample.m_fSpeedMultiplier = 3.0f; + switch (sampleIndex) { + case SFX_POLICE_HELI_1: + case SFX_POLICE_HELI_2: + case SFX_POLICE_HELI_3: + AudioManager.m_sQueueSample.m_fSoundIntensity = 400.0f; + break; + default: + AudioManager.m_sQueueSample.m_fSoundIntensity = 50.0f; + break; + } + AudioManager.m_sQueueSample.m_bReleasingSoundFlag = true; + AudioManager.m_sQueueSample.m_vecPos = m_asPedComments[m_nActiveBank][m_nIndexMap[m_nActiveBank][0]].m_vecPos; + + if (sampleIndex >= SFX_AMMU_D && sampleIndex <= SFX_AMMU_F) { + AudioManager.m_sQueueSample.m_bReverbFlag = false; + AudioManager.m_sQueueSample.m_bRequireReflection = false; + } else { + AudioManager.m_sQueueSample.m_bReverbFlag = true; + AudioManager.m_sQueueSample.m_bRequireReflection = true; + } + + AudioManager.m_sQueueSample.m_bIs2D = false; + AudioManager.m_sQueueSample.m_nFrequency = + SampleManager.GetSampleBaseFrequency(AudioManager.m_sQueueSample.m_nSampleIndex) + AudioManager.RandomDisplacement(750); + if (CTimer::GetIsSlowMotionActive()) + AudioManager.m_sQueueSample.m_nFrequency /= 2; + m_asPedComments[m_nActiveBank][m_nIndexMap[m_nActiveBank][0]].m_nProcess = -1; + AudioManager.AddSampleToRequestedQueue(); + } + + // Switch bank + if (m_nActiveBank) { + actualUsedBank = SAMPLEBANK_PED; + m_nActiveBank = SAMPLEBANK_MAIN; + } else { + actualUsedBank = SAMPLEBANK_MAIN; + m_nActiveBank = SAMPLEBANK_PED; + } + comment = m_asPedComments[actualUsedBank]; + for (uint32 i = 0; i < m_nCommentsInBank[actualUsedBank]; i++) { + if (m_asPedComments[actualUsedBank][m_nIndexMap[actualUsedBank][i]].m_nProcess > 0) { + --m_asPedComments[actualUsedBank][m_nIndexMap[actualUsedBank][i]].m_nProcess; + Add(&comment[m_nIndexMap[actualUsedBank][i]]); + } + } + + for (uint32 i = 0; i < NUM_PED_COMMENTS_SLOTS; i++) { + m_nIndexMap[actualUsedBank][i] = NUM_PED_COMMENTS_SLOTS; + } + m_nCommentsInBank[actualUsedBank] = 0; +} + +#pragma endregion + +#pragma endregion All the ped audio code + +void +cAudioManager::ProcessExplosions(int32 explosion) +{ + uint8 type; + CVector *pos; + float distSquared; + + for (uint8 i = 0; i < ARRAY_SIZE(gaExplosion); i++) { + if (CExplosion::GetExplosionActiveCounter(i) == 1) { + CExplosion::ResetExplosionActiveCounter(i); + type = CExplosion::GetExplosionType(i); + switch (type) { + case EXPLOSION_GRENADE: + case EXPLOSION_ROCKET: + case EXPLOSION_BARREL: + case EXPLOSION_TANK_GRENADE: + m_sQueueSample.m_fSoundIntensity = 400.0f; + m_sQueueSample.m_nSampleIndex = SFX_EXPLOSION_2; + m_sQueueSample.m_nFrequency = RandomDisplacement(2000) + 38000; + m_sQueueSample.m_nReleasingVolumeModificator = 0; + m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; + break; + case EXPLOSION_MOLOTOV: + m_sQueueSample.m_fSoundIntensity = 200.0f; + m_sQueueSample.m_nSampleIndex = SFX_EXPLOSION_3; + m_sQueueSample.m_nFrequency = RandomDisplacement(1000) + 19000; + m_sQueueSample.m_nReleasingVolumeModificator = 0; + m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; + break; + case EXPLOSION_MINE: + case EXPLOSION_HELI_BOMB: + m_sQueueSample.m_fSoundIntensity = 300.0f; + m_sQueueSample.m_nSampleIndex = SFX_ROCKET_LEFT; + m_sQueueSample.m_nFrequency = RandomDisplacement(1000) + 12347; + m_sQueueSample.m_nReleasingVolumeModificator = 0; + m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; + break; + default: + m_sQueueSample.m_fSoundIntensity = 400.0f; + m_sQueueSample.m_nSampleIndex = SFX_EXPLOSION_1; + m_sQueueSample.m_nFrequency = RandomDisplacement(2000) + 38000; + if (type == EXPLOSION_HELI) + m_sQueueSample.m_nFrequency = 8 * m_sQueueSample.m_nFrequency / 10; + m_sQueueSample.m_nReleasingVolumeModificator = 0; + m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; + break; + } + pos = CExplosion::GetExplosionPosition(i); + m_sQueueSample.m_vecPos = *pos; + distSquared = GetDistanceSquared(m_sQueueSample.m_vecPos); + if (distSquared < SQR(m_sQueueSample.m_fSoundIntensity)) { + m_sQueueSample.m_fDistance = Sqrt(distSquared); + m_sQueueSample.m_nVolume = ComputeVolume(MAX_VOLUME, m_sQueueSample.m_fSoundIntensity, m_sQueueSample.m_fDistance); + if (m_sQueueSample.m_nVolume != 0) { + m_sQueueSample.m_nCounter = i; + m_sQueueSample.m_fSpeedMultiplier = 2.0f; + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_nLoopCount = 1; + m_sQueueSample.m_bReleasingSoundFlag = true; + m_sQueueSample.m_bReverbFlag = true; + m_sQueueSample.m_nEmittingVolume = MAX_VOLUME; + m_sQueueSample.m_nLoopStart = 0; + m_sQueueSample.m_nLoopEnd = -1; + m_sQueueSample.m_bReverbFlag = true; + m_sQueueSample.m_bRequireReflection = true; + AddSampleToRequestedQueue(); + } + } + } + } +} + +void +cAudioManager::ProcessFires(int32) +{ + CEntity *entity; + uint8 emittingVol; + float distSquared; + + for (uint8 i = 0; i < NUM_FIRES; i++) { + if (gFireManager.m_aFires[i].m_bIsOngoing && gFireManager.m_aFires[i].m_bAudioSet) { + entity = gFireManager.m_aFires[i].m_pEntity; + if (entity) { + switch (entity->GetType()) { + case ENTITY_TYPE_BUILDING: + m_sQueueSample.m_fSoundIntensity = 50.0f; + m_sQueueSample.m_nSampleIndex = SFX_CAR_ON_FIRE; + emittingVol = 100; + m_sQueueSample.m_nFrequency = 8 * SampleManager.GetSampleBaseFrequency(SFX_CAR_ON_FIRE) / 10; + m_sQueueSample.m_nFrequency += i * (m_sQueueSample.m_nFrequency / 64); + m_sQueueSample.m_nReleasingVolumeModificator = 6; + break; + case ENTITY_TYPE_PED: + m_sQueueSample.m_fSoundIntensity = 25.0f; + m_sQueueSample.m_nSampleIndex = SFX_PED_ON_FIRE; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_PED_ON_FIRE); + emittingVol = 60; + m_sQueueSample.m_nFrequency += i * (m_sQueueSample.m_nFrequency / 64); + m_sQueueSample.m_nReleasingVolumeModificator = 10; + break; + default: + m_sQueueSample.m_fSoundIntensity = 50.0f; + m_sQueueSample.m_nSampleIndex = SFX_CAR_ON_FIRE; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_CAR_ON_FIRE); + m_sQueueSample.m_nFrequency += i * (m_sQueueSample.m_nFrequency / 64); + emittingVol = 80; + m_sQueueSample.m_nReleasingVolumeModificator = 8; + } + } else { + m_sQueueSample.m_fSoundIntensity = 50.0f; + m_sQueueSample.m_nSampleIndex = SFX_CAR_ON_FIRE; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_CAR_ON_FIRE); + m_sQueueSample.m_nFrequency += i * (m_sQueueSample.m_nFrequency / 64); + emittingVol = 80; + m_sQueueSample.m_nReleasingVolumeModificator = 8; + } + m_sQueueSample.m_vecPos = gFireManager.m_aFires[i].m_vecPos; + distSquared = GetDistanceSquared(m_sQueueSample.m_vecPos); + if (distSquared < SQR(m_sQueueSample.m_fSoundIntensity)) { + m_sQueueSample.m_fDistance = Sqrt(distSquared); + m_sQueueSample.m_nVolume = ComputeVolume(emittingVol, m_sQueueSample.m_fSoundIntensity, m_sQueueSample.m_fDistance); + if (m_sQueueSample.m_nVolume != 0) { + m_sQueueSample.m_nCounter = i; + m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; + m_sQueueSample.m_fSpeedMultiplier = 2.0f; + m_sQueueSample.m_nReleasingVolumeDivider = 10; + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_nLoopCount = 0; + m_sQueueSample.m_bReleasingSoundFlag = false; + m_sQueueSample.m_nEmittingVolume = emittingVol; + m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_bReverbFlag = true; + m_sQueueSample.m_bRequireReflection = false; + AddSampleToRequestedQueue(); + } + } + } + } +} + +void +cAudioManager::ProcessWaterCannon(int32) +{ + const float SOUND_INTENSITY = 900.0f; + + for (int32 i = 0; i < NUM_WATERCANNONS; i++) { + if (CWaterCannons::aCannons[i].m_nId) { + m_sQueueSample.m_vecPos = CWaterCannons::aCannons[0].m_avecPos[CWaterCannons::aCannons[i].m_nCur]; + float distSquared = GetDistanceSquared(m_sQueueSample.m_vecPos); + if (distSquared < SOUND_INTENSITY) { + m_sQueueSample.m_fDistance = Sqrt(distSquared); + m_sQueueSample.m_nVolume = ComputeVolume(50, m_sQueueSample.m_fSoundIntensity, m_sQueueSample.m_fDistance); + if (m_sQueueSample.m_nVolume != 0) { + m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY; + m_sQueueSample.m_nSampleIndex = SFX_JUMBO_TAXI; + m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; + m_sQueueSample.m_nFrequency = 15591; + m_sQueueSample.m_nReleasingVolumeModificator = 5; + m_sQueueSample.m_nCounter = i; + m_sQueueSample.m_fSpeedMultiplier = 2.0f; + m_sQueueSample.m_nReleasingVolumeDivider = 8; + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_nLoopCount = 0; + m_sQueueSample.m_bReleasingSoundFlag = false; + m_sQueueSample.m_nEmittingVolume = 50; + m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_bReverbFlag = true; + m_sQueueSample.m_bRequireReflection = false; + AddSampleToRequestedQueue(); + } + } + } + } +} + +#pragma region SCRIPT_OBJECTS +const int SCRIPT_OBJECT_INTENSITY_S = 30; +const int SCRIPT_OBJECT_INTENSITY_L = 80; + +void +cAudioManager::ProcessScriptObject(int32 id) +{ + cAudioScriptObject *entity = (cAudioScriptObject *)m_asAudioEntities[id].m_pEntity; + if (entity != nil) { + m_sQueueSample.m_vecPos = entity->Posn; + if (m_asAudioEntities[id].m_AudioEvents == 1) + ProcessOneShotScriptObject(m_asAudioEntities[id].m_awAudioEvent[0]); + else + ProcessLoopingScriptObject(entity->AudioId); + } +} + +void +cAudioManager::ProcessOneShotScriptObject(uint8 sound) +{ + CPlayerPed *playerPed; + uint8 emittingVolume; + float distSquared; + + cPedParams male; + cPedParams female; + + static uint8 iSound = 0; + + switch (sound) { + case SCRIPT_SOUND_INJURED_PED_MALE_OUCH_S: + case SCRIPT_SOUND_INJURED_PED_MALE_OUCH_L: + male.m_pPed = nil; + male.m_bDistanceCalculated = false; + male.m_fDistance = GetDistanceSquared(m_sQueueSample.m_vecPos); + SetupPedComments(&male, SOUND_INJURED_PED_MALE_OUCH); + return; + case SCRIPT_SOUND_INJURED_PED_FEMALE_OUCH_S: + case SCRIPT_SOUND_INJURED_PED_FEMALE_OUCH_L: + female.m_pPed = nil; + female.m_bDistanceCalculated = false; + female.m_fDistance = GetDistanceSquared(m_sQueueSample.m_vecPos); + SetupPedComments(&female, SOUND_INJURED_PED_FEMALE); + return; + case SCRIPT_SOUND_GATE_START_CLUNK: + case SCRIPT_SOUND_GATE_STOP_CLUNK: + m_sQueueSample.m_fSoundIntensity = 40.0f; + m_sQueueSample.m_nSampleIndex = SFX_COL_GATE; + m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; + if (sound == SCRIPT_SOUND_GATE_START_CLUNK) + m_sQueueSample.m_nFrequency = 10600; + else + m_sQueueSample.m_nFrequency = 9000; + m_sQueueSample.m_nReleasingVolumeModificator = 1; + m_sQueueSample.m_fSpeedMultiplier = 0.0f; + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_bRequireReflection = true; + emittingVolume = RandomDisplacement(10) + 50; + break; + case SCRIPT_SOUND_BULLET_HIT_GROUND_1: + case SCRIPT_SOUND_BULLET_HIT_GROUND_2: + case SCRIPT_SOUND_BULLET_HIT_GROUND_3: + m_sQueueSample.m_fSoundIntensity = 50.0f; + m_sQueueSample.m_nSampleIndex = m_anRandomTable[iSound % 5] % 3 + SFX_BULLET_WALL_1; + m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_nFrequency += RandomDisplacement(m_sQueueSample.m_nFrequency / 32); + m_sQueueSample.m_nReleasingVolumeModificator = 9; + m_sQueueSample.m_fSpeedMultiplier = 0.0f; + m_sQueueSample.m_bIs2D = false; + emittingVolume = m_anRandomTable[2] % 20 + 90; + break; + case SCRIPT_SOUND_110: + case SCRIPT_SOUND_111: + if (SampleManager.IsSampleBankLoaded(0) != 1) + return; + m_sQueueSample.m_fSoundIntensity = 80.0f; + m_sQueueSample.m_nSampleIndex = SFX_TRAIN_STATION_ANNOUNCE; + m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; + emittingVolume = MAX_VOLUME; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_TRAIN_STATION_ANNOUNCE); + m_sQueueSample.m_nReleasingVolumeModificator = 0; + m_sQueueSample.m_fSpeedMultiplier = 2.0f; + m_sQueueSample.m_bIs2D = false; + break; + case SCRIPT_SOUND_PAYPHONE_RINGING: + m_sQueueSample.m_fSoundIntensity = 80.0f; + m_sQueueSample.m_nSampleIndex = SFX_PHONE_RING; + m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; + emittingVolume = 80; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_PHONE_RING); + m_sQueueSample.m_nReleasingVolumeModificator = 1; + m_sQueueSample.m_fSpeedMultiplier = 2.0f; + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_bRequireReflection = false; + break; + case SCRIPT_SOUND_GLASS_BREAK_L: + m_sQueueSample.m_fSoundIntensity = 60.0f; + m_sQueueSample.m_nSampleIndex = SFX_GLASS_SMASH; + m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; + emittingVolume = 70; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_GLASS_SMASH); + m_sQueueSample.m_nReleasingVolumeModificator = 3; + m_sQueueSample.m_fSpeedMultiplier = 0.0f; + m_sQueueSample.m_bIs2D = false; + break; + case SCRIPT_SOUND_GLASS_BREAK_S: + m_sQueueSample.m_fSoundIntensity = 60.0f; + m_sQueueSample.m_nSampleIndex = SFX_GLASS_SMASH; + m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; + emittingVolume = 60; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_GLASS_SMASH); + m_sQueueSample.m_nReleasingVolumeModificator = 3; + m_sQueueSample.m_fSpeedMultiplier = 0.0f; + m_sQueueSample.m_bIs2D = false; + break; + case SCRIPT_SOUND_GLASS_CRACK: + m_sQueueSample.m_fSoundIntensity = 60.0f; + m_sQueueSample.m_nSampleIndex = SFX_GLASS_CRACK; + m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; + emittingVolume = 70; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_GLASS_CRACK); + m_sQueueSample.m_nReleasingVolumeModificator = 3; + m_sQueueSample.m_fSpeedMultiplier = 0.0f; + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_bRequireReflection = true; + break; + case SCRIPT_SOUND_GLASS_LIGHT_BREAK: + m_sQueueSample.m_fSoundIntensity = 55.0f; + m_sQueueSample.m_nSampleIndex = (m_anRandomTable[4] & 3) + SFX_GLASS_SHARD_1; + m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; + m_sQueueSample.m_nFrequency = RandomDisplacement(2000) + 19000; + m_sQueueSample.m_nReleasingVolumeModificator = 9; + m_sQueueSample.m_fSpeedMultiplier = 0.0f; + m_sQueueSample.m_bIs2D = false; + emittingVolume = RandomDisplacement(11) + 25; + break; + case SCRIPT_SOUND_BOX_DESTROYED_1: + m_sQueueSample.m_fSoundIntensity = 60.0f; + m_sQueueSample.m_nSampleIndex = SFX_WOODEN_BOX_SMASH; + m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; + m_sQueueSample.m_nFrequency = RandomDisplacement(1500) + 18600; + m_sQueueSample.m_nReleasingVolumeModificator = 3; + m_sQueueSample.m_fSpeedMultiplier = 0.0f; + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_bRequireReflection = true; + emittingVolume = m_anRandomTable[2] % 20 + 80; + break; + case SCRIPT_SOUND_BOX_DESTROYED_2: + m_sQueueSample.m_fSoundIntensity = 60.0f; + m_sQueueSample.m_nSampleIndex = SFX_CARDBOARD_BOX_SMASH; + m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; + m_sQueueSample.m_nFrequency = RandomDisplacement(1500) + 18600; + m_sQueueSample.m_nReleasingVolumeModificator = 3; + m_sQueueSample.m_fSpeedMultiplier = 0.0f; + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_bRequireReflection = true; + emittingVolume = m_anRandomTable[2] % 20 + 80; + break; + case SCRIPT_SOUND_METAL_COLLISION: + m_sQueueSample.m_fSoundIntensity = 60.0f; + m_sQueueSample.m_nSampleIndex = m_anRandomTable[3] % 5 + SFX_COL_CAR_1; + m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_nFrequency += RandomDisplacement(m_sQueueSample.m_nFrequency / 16); + m_sQueueSample.m_nReleasingVolumeModificator = 3; + m_sQueueSample.m_fSpeedMultiplier = 0.0f; + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_bRequireReflection = true; + emittingVolume = m_anRandomTable[2] % 30 + 70; + break; + case SCRIPT_SOUND_TIRE_COLLISION: + m_sQueueSample.m_fSoundIntensity = 60.0f; + m_sQueueSample.m_nSampleIndex = SFX_TYRE_BUMP; + m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_nFrequency += RandomDisplacement(m_sQueueSample.m_nFrequency / 16); + m_sQueueSample.m_nReleasingVolumeModificator = 3; + m_sQueueSample.m_fSpeedMultiplier = 0.0f; + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_bRequireReflection = true; + emittingVolume = m_anRandomTable[2] % 30 + 60; + break; + case SCRIPT_SOUND_GUNSHELL_DROP: + playerPed = FindPlayerPed(); + if (playerPed) { + switch (playerPed->m_nSurfaceTouched) { + case SURFACE_GRASS: + case SURFACE_GRAVEL: + case SURFACE_MUD_DRY: + case SURFACE_TRANSPARENT_CLOTH: + case SURFACE_PED: + case SURFACE_SAND: + case SURFACE_RUBBER: + case SURFACE_HEDGE: + m_sQueueSample.m_nSampleIndex = SFX_BULLET_SHELL_HIT_GROUND_2; + m_sQueueSample.m_nFrequency = RandomDisplacement(500) + 11000; + m_sQueueSample.m_nReleasingVolumeModificator = 18; + m_sQueueSample.m_fSoundIntensity = 20.0f; + m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; + m_sQueueSample.m_fSpeedMultiplier = 0.0f; + m_sQueueSample.m_bIs2D = false; + emittingVolume = m_anRandomTable[2] % 20 + 30; + distSquared = GetDistanceSquared(m_sQueueSample.m_vecPos); + if (distSquared < SQR(m_sQueueSample.m_fSoundIntensity)) { + m_sQueueSample.m_fDistance = Sqrt(distSquared); + m_sQueueSample.m_nVolume = ComputeVolume(emittingVolume, m_sQueueSample.m_fSoundIntensity, m_sQueueSample.m_fDistance); + if (m_sQueueSample.m_nVolume != 0) { + m_sQueueSample.m_nCounter = iSound++; + m_sQueueSample.m_nLoopCount = 1; + m_sQueueSample.m_bReleasingSoundFlag = true; + m_sQueueSample.m_nEmittingVolume = emittingVolume; + m_sQueueSample.m_nLoopStart = 0; + m_sQueueSample.m_nLoopEnd = -1; + m_sQueueSample.m_bReverbFlag = true; + AddSampleToRequestedQueue(); + } + } + return; + case SURFACE_WATER: + return; + default: + break; + } + } + m_sQueueSample.m_nSampleIndex = SFX_BULLET_SHELL_HIT_GROUND_1; + m_sQueueSample.m_nFrequency = RandomDisplacement(750) + 18000; + m_sQueueSample.m_nReleasingVolumeModificator = 15; + m_sQueueSample.m_fSoundIntensity = 20.0f; + m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; + m_sQueueSample.m_fSpeedMultiplier = 0.0f; + m_sQueueSample.m_bIs2D = false; + emittingVolume = m_anRandomTable[2] % 20 + 30; + break; + case SCRIPT_SOUND_GUNSHELL_DROP_SOFT: + m_sQueueSample.m_nSampleIndex = SFX_BULLET_SHELL_HIT_GROUND_2; + m_sQueueSample.m_nFrequency = RandomDisplacement(500) + 11000; + m_sQueueSample.m_nReleasingVolumeModificator = 18; + m_sQueueSample.m_fSoundIntensity = 20.0f; + m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; + m_sQueueSample.m_fSpeedMultiplier = 0.0f; + m_sQueueSample.m_bIs2D = false; + emittingVolume = m_anRandomTable[2] % 20 + 30; + break; + default: + return; + } + + distSquared = GetDistanceSquared(m_sQueueSample.m_vecPos); + if (distSquared < SQR(m_sQueueSample.m_fSoundIntensity)) { + m_sQueueSample.m_fDistance = Sqrt(distSquared); + m_sQueueSample.m_nVolume = ComputeVolume(emittingVolume, m_sQueueSample.m_fSoundIntensity, m_sQueueSample.m_fDistance); + if (m_sQueueSample.m_nVolume != 0) { + m_sQueueSample.m_nCounter = iSound++; + m_sQueueSample.m_nLoopCount = 1; + m_sQueueSample.m_bReleasingSoundFlag = true; + m_sQueueSample.m_nEmittingVolume = emittingVolume; + m_sQueueSample.m_nLoopStart = 0; + m_sQueueSample.m_nLoopEnd = -1; + m_sQueueSample.m_bReverbFlag = true; + AddSampleToRequestedQueue(); + } + } +} + +void +cAudioManager::ProcessLoopingScriptObject(uint8 sound) +{ + uint8 emittingVolume; + float distSquared; + + switch (sound) { + case SCRIPT_SOUND_PARTY_1_LOOP_S: + m_sQueueSample.m_fSoundIntensity = SCRIPT_OBJECT_INTENSITY_S; + m_sQueueSample.m_nSampleIndex = SFX_CLUB_1; + m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; + emittingVolume = MAX_VOLUME; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_CLUB_1); + m_sQueueSample.m_nReleasingVolumeModificator = 3; + m_sQueueSample.m_nReleasingVolumeDivider = 3; + m_sQueueSample.m_fSpeedMultiplier = 2.0f; + break; + case SCRIPT_SOUND_PARTY_1_LOOP_L: + m_sQueueSample.m_fSoundIntensity = SCRIPT_OBJECT_INTENSITY_L; + m_sQueueSample.m_nSampleIndex = SFX_CLUB_1; + m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; + emittingVolume = MAX_VOLUME; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_CLUB_1); + m_sQueueSample.m_nReleasingVolumeModificator = 3; + m_sQueueSample.m_nReleasingVolumeDivider = 3; + m_sQueueSample.m_fSpeedMultiplier = 2.0f; + break; + case SCRIPT_SOUND_PARTY_2_LOOP_S: + m_sQueueSample.m_fSoundIntensity = SCRIPT_OBJECT_INTENSITY_S; + m_sQueueSample.m_nSampleIndex = SFX_CLUB_2; + m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; + emittingVolume = MAX_VOLUME; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_CLUB_2); + m_sQueueSample.m_nReleasingVolumeModificator = 3; + m_sQueueSample.m_nReleasingVolumeDivider = 3; + m_sQueueSample.m_fSpeedMultiplier = 2.0f; + break; + case SCRIPT_SOUND_PARTY_2_LOOP_L: + m_sQueueSample.m_fSoundIntensity = SCRIPT_OBJECT_INTENSITY_L; + m_sQueueSample.m_nSampleIndex = SFX_CLUB_2; + m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; + emittingVolume = MAX_VOLUME; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_CLUB_2); + m_sQueueSample.m_nReleasingVolumeModificator = 3; + m_sQueueSample.m_nReleasingVolumeDivider = 3; + m_sQueueSample.m_fSpeedMultiplier = 2.0f; + break; + case SCRIPT_SOUND_PARTY_3_LOOP_S: + m_sQueueSample.m_fSoundIntensity = SCRIPT_OBJECT_INTENSITY_S; + m_sQueueSample.m_nSampleIndex = SFX_CLUB_3; + m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; + emittingVolume = MAX_VOLUME; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_CLUB_3); + m_sQueueSample.m_nReleasingVolumeModificator = 3; + m_sQueueSample.m_nReleasingVolumeDivider = 3; + m_sQueueSample.m_fSpeedMultiplier = 2.0f; + break; + case SCRIPT_SOUND_PARTY_3_LOOP_L: + m_sQueueSample.m_fSoundIntensity = SCRIPT_OBJECT_INTENSITY_L; + m_sQueueSample.m_nSampleIndex = SFX_CLUB_3; + m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; + emittingVolume = MAX_VOLUME; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_CLUB_3); + m_sQueueSample.m_nReleasingVolumeModificator = 3; + m_sQueueSample.m_nReleasingVolumeDivider = 3; + m_sQueueSample.m_fSpeedMultiplier = 2.0f; + break; + case SCRIPT_SOUND_PARTY_4_LOOP_S: + m_sQueueSample.m_fSoundIntensity = SCRIPT_OBJECT_INTENSITY_S; + m_sQueueSample.m_nSampleIndex = SFX_CLUB_4; + m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; + emittingVolume = MAX_VOLUME; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_CLUB_4); + m_sQueueSample.m_nReleasingVolumeModificator = 3; + m_sQueueSample.m_nReleasingVolumeDivider = 3; + m_sQueueSample.m_fSpeedMultiplier = 2.0f; + break; + case SCRIPT_SOUND_PARTY_4_LOOP_L: + m_sQueueSample.m_fSoundIntensity = SCRIPT_OBJECT_INTENSITY_L; + m_sQueueSample.m_nSampleIndex = SFX_CLUB_4; + m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; + emittingVolume = MAX_VOLUME; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_CLUB_4); + m_sQueueSample.m_nReleasingVolumeModificator = 3; + m_sQueueSample.m_nReleasingVolumeDivider = 3; + m_sQueueSample.m_fSpeedMultiplier = 2.0f; + break; + case SCRIPT_SOUND_PARTY_5_LOOP_S: + m_sQueueSample.m_fSoundIntensity = SCRIPT_OBJECT_INTENSITY_S; + m_sQueueSample.m_nSampleIndex = SFX_CLUB_5; + m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; + emittingVolume = MAX_VOLUME; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_CLUB_5); + m_sQueueSample.m_nReleasingVolumeModificator = 3; + m_sQueueSample.m_nReleasingVolumeDivider = 3; + m_sQueueSample.m_fSpeedMultiplier = 2.0f; + break; + case SCRIPT_SOUND_PARTY_5_LOOP_L: + m_sQueueSample.m_fSoundIntensity = SCRIPT_OBJECT_INTENSITY_L; + m_sQueueSample.m_nSampleIndex = SFX_CLUB_5; + m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; + emittingVolume = MAX_VOLUME; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_CLUB_5); + m_sQueueSample.m_nReleasingVolumeModificator = 3; + m_sQueueSample.m_nReleasingVolumeDivider = 3; + m_sQueueSample.m_fSpeedMultiplier = 2.0f; + break; + case SCRIPT_SOUND_PARTY_6_LOOP_S: + m_sQueueSample.m_fSoundIntensity = SCRIPT_OBJECT_INTENSITY_S; + m_sQueueSample.m_nSampleIndex = SFX_CLUB_6; + m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; + emittingVolume = MAX_VOLUME; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_CLUB_6); + m_sQueueSample.m_nReleasingVolumeModificator = 3; + m_sQueueSample.m_nReleasingVolumeDivider = 3; + m_sQueueSample.m_fSpeedMultiplier = 2.0f; + break; + case SCRIPT_SOUND_PARTY_6_LOOP_L: + m_sQueueSample.m_fSoundIntensity = SCRIPT_OBJECT_INTENSITY_L; + m_sQueueSample.m_nSampleIndex = SFX_CLUB_6; + m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; + emittingVolume = MAX_VOLUME; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_CLUB_6); + m_sQueueSample.m_nReleasingVolumeModificator = 3; + m_sQueueSample.m_nReleasingVolumeDivider = 3; + m_sQueueSample.m_fSpeedMultiplier = 2.0f; + break; + case SCRIPT_SOUND_PARTY_7_LOOP_S: + m_sQueueSample.m_fSoundIntensity = SCRIPT_OBJECT_INTENSITY_S; + m_sQueueSample.m_nSampleIndex = SFX_CLUB_7; + m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; + emittingVolume = MAX_VOLUME; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_CLUB_7); + m_sQueueSample.m_nReleasingVolumeModificator = 3; + m_sQueueSample.m_nReleasingVolumeDivider = 3; + m_sQueueSample.m_fSpeedMultiplier = 2.0f; + break; + case SCRIPT_SOUND_PARTY_7_LOOP_L: + m_sQueueSample.m_fSoundIntensity = SCRIPT_OBJECT_INTENSITY_L; + m_sQueueSample.m_nSampleIndex = SFX_CLUB_7; + m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; + emittingVolume = MAX_VOLUME; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_CLUB_7); + m_sQueueSample.m_nReleasingVolumeModificator = 3; + m_sQueueSample.m_nReleasingVolumeDivider = 3; + m_sQueueSample.m_fSpeedMultiplier = 2.0f; + break; + case SCRIPT_SOUND_PARTY_8_LOOP_S: + m_sQueueSample.m_fSoundIntensity = SCRIPT_OBJECT_INTENSITY_S; + m_sQueueSample.m_nSampleIndex = SFX_CLUB_8; + m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; + emittingVolume = MAX_VOLUME; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_CLUB_8); + m_sQueueSample.m_nReleasingVolumeModificator = 3; + m_sQueueSample.m_nReleasingVolumeDivider = 3; + m_sQueueSample.m_fSpeedMultiplier = 2.0f; + break; + case SCRIPT_SOUND_PARTY_8_LOOP_L: + m_sQueueSample.m_fSoundIntensity = SCRIPT_OBJECT_INTENSITY_L; + m_sQueueSample.m_nSampleIndex = SFX_CLUB_8; + m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; + emittingVolume = MAX_VOLUME; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_CLUB_8); + m_sQueueSample.m_nReleasingVolumeModificator = 3; + m_sQueueSample.m_nReleasingVolumeDivider = 3; + m_sQueueSample.m_fSpeedMultiplier = 2.0f; + break; + case SCRIPT_SOUND_PARTY_9_LOOP_S: + m_sQueueSample.m_fSoundIntensity = SCRIPT_OBJECT_INTENSITY_S; + m_sQueueSample.m_nSampleIndex = SFX_CLUB_9; + m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; + emittingVolume = MAX_VOLUME; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_CLUB_9); + m_sQueueSample.m_nReleasingVolumeModificator = 3; + m_sQueueSample.m_nReleasingVolumeDivider = 3; + m_sQueueSample.m_fSpeedMultiplier = 2.0f; + break; + case SCRIPT_SOUND_PARTY_9_LOOP_L: + m_sQueueSample.m_fSoundIntensity = SCRIPT_OBJECT_INTENSITY_L; + m_sQueueSample.m_nSampleIndex = SFX_CLUB_9; + m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; + emittingVolume = MAX_VOLUME; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_CLUB_9); + m_sQueueSample.m_nReleasingVolumeModificator = 3; + m_sQueueSample.m_nReleasingVolumeDivider = 3; + m_sQueueSample.m_fSpeedMultiplier = 2.0f; + break; + case SCRIPT_SOUND_PARTY_10_LOOP_S: + m_sQueueSample.m_fSoundIntensity = SCRIPT_OBJECT_INTENSITY_S; + m_sQueueSample.m_nSampleIndex = SFX_CLUB_10; + m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; + emittingVolume = MAX_VOLUME; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_CLUB_10); + m_sQueueSample.m_nReleasingVolumeModificator = 3; + m_sQueueSample.m_nReleasingVolumeDivider = 3; + m_sQueueSample.m_fSpeedMultiplier = 2.0f; + break; + case SCRIPT_SOUND_PARTY_10_LOOP_L: + m_sQueueSample.m_fSoundIntensity = SCRIPT_OBJECT_INTENSITY_L; + m_sQueueSample.m_nSampleIndex = SFX_CLUB_10; + m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; + emittingVolume = MAX_VOLUME; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_CLUB_10); + m_sQueueSample.m_nReleasingVolumeModificator = 3; + m_sQueueSample.m_nReleasingVolumeDivider = 3; + m_sQueueSample.m_fSpeedMultiplier = 2.0f; + break; + case SCRIPT_SOUND_PARTY_11_LOOP_S: + m_sQueueSample.m_fSoundIntensity = SCRIPT_OBJECT_INTENSITY_S; + m_sQueueSample.m_nSampleIndex = SFX_CLUB_11; + m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; + emittingVolume = MAX_VOLUME; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_CLUB_11); + m_sQueueSample.m_nReleasingVolumeModificator = 3; + m_sQueueSample.m_nReleasingVolumeDivider = 3; + m_sQueueSample.m_fSpeedMultiplier = 2.0f; + break; + case SCRIPT_SOUND_PARTY_11_LOOP_L: + m_sQueueSample.m_fSoundIntensity = SCRIPT_OBJECT_INTENSITY_L; + m_sQueueSample.m_nSampleIndex = SFX_CLUB_11; + m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; + emittingVolume = MAX_VOLUME; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_CLUB_11); + m_sQueueSample.m_nReleasingVolumeModificator = 3; + m_sQueueSample.m_nReleasingVolumeDivider = 3; + m_sQueueSample.m_fSpeedMultiplier = 2.0f; + break; + case SCRIPT_SOUND_PARTY_12_LOOP_S: + m_sQueueSample.m_fSoundIntensity = SCRIPT_OBJECT_INTENSITY_S; + m_sQueueSample.m_nSampleIndex = SFX_CLUB_12; + m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; + emittingVolume = MAX_VOLUME; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_CLUB_12); + m_sQueueSample.m_nReleasingVolumeModificator = 3; + m_sQueueSample.m_nReleasingVolumeDivider = 3; + m_sQueueSample.m_fSpeedMultiplier = 2.0f; + break; + case SCRIPT_SOUND_PARTY_12_LOOP_L: + m_sQueueSample.m_fSoundIntensity = SCRIPT_OBJECT_INTENSITY_L; + m_sQueueSample.m_nSampleIndex = SFX_CLUB_12; + m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; + emittingVolume = MAX_VOLUME; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_CLUB_12); + m_sQueueSample.m_nReleasingVolumeModificator = 3; + m_sQueueSample.m_nReleasingVolumeDivider = 3; + m_sQueueSample.m_fSpeedMultiplier = 2.0f; + break; + case SCRIPT_SOUND_PARTY_13_LOOP_S: + m_sQueueSample.m_fSoundIntensity = SCRIPT_OBJECT_INTENSITY_S; + m_sQueueSample.m_nSampleIndex = SFX_CLUB_RAGGA; + m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; + emittingVolume = MAX_VOLUME; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_CLUB_RAGGA); + m_sQueueSample.m_nReleasingVolumeModificator = 3; + m_sQueueSample.m_nReleasingVolumeDivider = 3; + m_sQueueSample.m_fSpeedMultiplier = 2.0f; + break; + case SCRIPT_SOUND_PARTY_13_LOOP_L: + m_sQueueSample.m_fSoundIntensity = SCRIPT_OBJECT_INTENSITY_L; + m_sQueueSample.m_nSampleIndex = SFX_CLUB_RAGGA; + m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; + emittingVolume = MAX_VOLUME; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_CLUB_RAGGA); + m_sQueueSample.m_nReleasingVolumeModificator = 3; + m_sQueueSample.m_nReleasingVolumeDivider = 3; + m_sQueueSample.m_fSpeedMultiplier = 2.0f; + break; + case SCRIPT_SOUND_STRIP_CLUB_LOOP_1_S: + m_sQueueSample.m_fSoundIntensity = SCRIPT_OBJECT_INTENSITY_S; + m_sQueueSample.m_nSampleIndex = SFX_STRIP_CLUB_1; + m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; + emittingVolume = MAX_VOLUME; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_STRIP_CLUB_1); + m_sQueueSample.m_nReleasingVolumeModificator = 3; + m_sQueueSample.m_nReleasingVolumeDivider = 3; + m_sQueueSample.m_fSpeedMultiplier = 2.0f; + break; + case SCRIPT_SOUND_STRIP_CLUB_LOOP_1_L: + m_sQueueSample.m_fSoundIntensity = SCRIPT_OBJECT_INTENSITY_L; + m_sQueueSample.m_nSampleIndex = SFX_STRIP_CLUB_1; + m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; + emittingVolume = MAX_VOLUME; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_STRIP_CLUB_1); + m_sQueueSample.m_nReleasingVolumeModificator = 3; + m_sQueueSample.m_nReleasingVolumeDivider = 3; + m_sQueueSample.m_fSpeedMultiplier = 2.0f; + break; + case SCRIPT_SOUND_STRIP_CLUB_LOOP_2_S: + m_sQueueSample.m_fSoundIntensity = SCRIPT_OBJECT_INTENSITY_S; + m_sQueueSample.m_nSampleIndex = SFX_STRIP_CLUB_2; + m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; + emittingVolume = MAX_VOLUME; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_STRIP_CLUB_2); + m_sQueueSample.m_nReleasingVolumeModificator = 3; + m_sQueueSample.m_nReleasingVolumeDivider = 3; + m_sQueueSample.m_fSpeedMultiplier = 2.0f; + break; + case SCRIPT_SOUND_STRIP_CLUB_LOOP_2_L: + m_sQueueSample.m_fSoundIntensity = SCRIPT_OBJECT_INTENSITY_L; + m_sQueueSample.m_nSampleIndex = SFX_STRIP_CLUB_2; + m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; + emittingVolume = MAX_VOLUME; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_STRIP_CLUB_2); + m_sQueueSample.m_nReleasingVolumeModificator = 3; + m_sQueueSample.m_nReleasingVolumeDivider = 3; + m_sQueueSample.m_fSpeedMultiplier = 2.0f; + break; + case SCRIPT_SOUND_WORK_SHOP_LOOP_S: + case SCRIPT_SOUND_WORK_SHOP_LOOP_L: + ProcessWorkShopScriptObject(sound); + return; + case SCRIPT_SOUND_SAWMILL_LOOP_S: + case SCRIPT_SOUND_SAWMILL_LOOP_L: + ProcessSawMillScriptObject(sound); + return; + case SCRIPT_SOUND_38: + m_sQueueSample.m_fSoundIntensity = SCRIPT_OBJECT_INTENSITY_S; + m_sQueueSample.m_nSampleIndex = SFX_DOG_FOOD_FACTORY; + m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; + emittingVolume = 110; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_DOG_FOOD_FACTORY); + m_sQueueSample.m_nReleasingVolumeModificator = 6; + m_sQueueSample.m_nReleasingVolumeDivider = 3; + m_sQueueSample.m_fSpeedMultiplier = 2.0f; + break; + case SCRIPT_SOUND_39: + m_sQueueSample.m_fSoundIntensity = SCRIPT_OBJECT_INTENSITY_L; + m_sQueueSample.m_nSampleIndex = SFX_DOG_FOOD_FACTORY; + m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; + emittingVolume = 110; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_DOG_FOOD_FACTORY); + m_sQueueSample.m_nReleasingVolumeModificator = 6; + m_sQueueSample.m_nReleasingVolumeDivider = 3; + m_sQueueSample.m_fSpeedMultiplier = 2.0f; + break; + case SCRIPT_SOUND_LAUNDERETTE_LOOP_S: + case SCRIPT_SOUND_LAUNDERETTE_LOOP_L: + ProcessLaunderetteScriptObject(sound); + return; + case SCRIPT_SOUND_CHINATOWN_RESTAURANT_S: + m_sQueueSample.m_fSoundIntensity = SCRIPT_OBJECT_INTENSITY_S; + m_sQueueSample.m_nSampleIndex = SFX_RESTAURANT_CHINATOWN; + m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; + emittingVolume = 110; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_RESTAURANT_CHINATOWN); + m_sQueueSample.m_nReleasingVolumeModificator = 3; + m_sQueueSample.m_nReleasingVolumeDivider = 3; + m_sQueueSample.m_fSpeedMultiplier = 2.0f; + break; + case SCRIPT_SOUND_CHINATOWN_RESTAURANT_L: + m_sQueueSample.m_fSoundIntensity = SCRIPT_OBJECT_INTENSITY_L; + m_sQueueSample.m_nSampleIndex = SFX_RESTAURANT_CHINATOWN; + m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; + emittingVolume = 110; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_RESTAURANT_CHINATOWN); + m_sQueueSample.m_nReleasingVolumeModificator = 3; + m_sQueueSample.m_nReleasingVolumeDivider = 3; + m_sQueueSample.m_fSpeedMultiplier = 2.0f; + break; + case SCRIPT_SOUND_CIPRIANI_RESAURANT_S: + m_sQueueSample.m_fSoundIntensity = SCRIPT_OBJECT_INTENSITY_S; + m_sQueueSample.m_nSampleIndex = SFX_RESTAURANT_ITALY; + m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; + emittingVolume = 110; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_RESTAURANT_ITALY); + m_sQueueSample.m_nReleasingVolumeModificator = 3; + m_sQueueSample.m_nReleasingVolumeDivider = 3; + m_sQueueSample.m_fSpeedMultiplier = 2.0f; + break; + case SCRIPT_SOUND_CIPRIANI_RESAURANT_L: + m_sQueueSample.m_fSoundIntensity = SCRIPT_OBJECT_INTENSITY_L; + m_sQueueSample.m_nSampleIndex = SFX_RESTAURANT_ITALY; + m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; + emittingVolume = 110; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_RESTAURANT_ITALY); + m_sQueueSample.m_nReleasingVolumeModificator = 3; + m_sQueueSample.m_nReleasingVolumeDivider = 3; + m_sQueueSample.m_fSpeedMultiplier = 2.0f; + break; + case SCRIPT_SOUND_46_S: + m_sQueueSample.m_fSoundIntensity = SCRIPT_OBJECT_INTENSITY_S; + m_sQueueSample.m_nSampleIndex = SFX_RESTAURANT_GENERIC_1; + m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; + emittingVolume = 110; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_RESTAURANT_GENERIC_1); + m_sQueueSample.m_nReleasingVolumeModificator = 3; + m_sQueueSample.m_nReleasingVolumeDivider = 3; + m_sQueueSample.m_fSpeedMultiplier = 2.0f; + break; + case SCRIPT_SOUND_47_L: + m_sQueueSample.m_fSoundIntensity = SCRIPT_OBJECT_INTENSITY_L; + m_sQueueSample.m_nSampleIndex = SFX_RESTAURANT_GENERIC_1; + m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; + emittingVolume = 110; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_RESTAURANT_GENERIC_1); + m_sQueueSample.m_nReleasingVolumeModificator = 3; + m_sQueueSample.m_nReleasingVolumeDivider = 3; + m_sQueueSample.m_fSpeedMultiplier = 2.0f; + break; + case SCRIPT_SOUND_MARCO_BISTRO_S: + m_sQueueSample.m_fSoundIntensity = SCRIPT_OBJECT_INTENSITY_S; + m_sQueueSample.m_nSampleIndex = SFX_RESTAURANT_GENERIC_2; + m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; + emittingVolume = 110; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_RESTAURANT_GENERIC_2); + m_sQueueSample.m_nReleasingVolumeModificator = 3; + m_sQueueSample.m_nReleasingVolumeDivider = 3; + m_sQueueSample.m_fSpeedMultiplier = 2.0f; + break; + case SCRIPT_SOUND_MARCO_BISTRO_L: + m_sQueueSample.m_fSoundIntensity = SCRIPT_OBJECT_INTENSITY_L; + m_sQueueSample.m_nSampleIndex = SFX_RESTAURANT_GENERIC_2; + m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; + emittingVolume = 110; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_RESTAURANT_GENERIC_2); + m_sQueueSample.m_nReleasingVolumeModificator = 3; + m_sQueueSample.m_nReleasingVolumeDivider = 3; + m_sQueueSample.m_fSpeedMultiplier = 2.0f; + break; + case SCRIPT_SOUND_AIRPORT_LOOP_S: + case SCRIPT_SOUND_AIRPORT_LOOP_L: + ProcessAirportScriptObject(sound); + return; + case SCRIPT_SOUND_SHOP_LOOP_S: + case SCRIPT_SOUND_SHOP_LOOP_L: + ProcessShopScriptObject(sound); + return; + case SCRIPT_SOUND_CINEMA_LOOP_S: + case SCRIPT_SOUND_CINEMA_LOOP_L: + ProcessCinemaScriptObject(sound); + return; + case SCRIPT_SOUND_DOCKS_LOOP_S: + case SCRIPT_SOUND_DOCKS_LOOP_L: + ProcessDocksScriptObject(sound); + return; + case SCRIPT_SOUND_HOME_LOOP_S: + case SCRIPT_SOUND_HOME_LOOP_L: + ProcessHomeScriptObject(sound); + return; + case SCRIPT_SOUND_FRANKIE_PIANO: + m_sQueueSample.m_fSoundIntensity = SCRIPT_OBJECT_INTENSITY_S; + m_sQueueSample.m_nSampleIndex = SFX_PIANO_BAR_1; + m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; + emittingVolume = MAX_VOLUME; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_PIANO_BAR_1); + m_sQueueSample.m_nReleasingVolumeModificator = 3; + m_sQueueSample.m_nReleasingVolumeDivider = 3; + m_sQueueSample.m_fSpeedMultiplier = 2.0f; + break; + case SCRIPT_SOUND_PARTY_1_LOOP: + m_sQueueSample.m_fSoundIntensity = SCRIPT_OBJECT_INTENSITY_L; + m_sQueueSample.m_nSampleIndex = SFX_CLUB_1; + m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; + emittingVolume = MAX_VOLUME; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_CLUB_1); + m_sQueueSample.m_nReleasingVolumeModificator = 3; + m_sQueueSample.m_nReleasingVolumeDivider = 3; + m_sQueueSample.m_fSpeedMultiplier = 2.0f; + break; + case SCRIPT_SOUND_PORN_CINEMA_1_S: + case SCRIPT_SOUND_PORN_CINEMA_1_L: + case SCRIPT_SOUND_PORN_CINEMA_2_S: + case SCRIPT_SOUND_PORN_CINEMA_2_L: + case SCRIPT_SOUND_PORN_CINEMA_3_S: + case SCRIPT_SOUND_PORN_CINEMA_3_L: + case SCRIPT_SOUND_MISTY_SEX_S: + case SCRIPT_SOUND_MISTY_SEX_L: + ProcessPornCinema(sound); + return; + case SCRIPT_SOUND_BANK_ALARM_LOOP_S: + m_sQueueSample.m_fSoundIntensity = SCRIPT_OBJECT_INTENSITY_S; + m_sQueueSample.m_nSampleIndex = SFX_BANK_ALARM_1; + m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; + emittingVolume = 90; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_BANK_ALARM_1); + m_sQueueSample.m_nReleasingVolumeModificator = 2; + m_sQueueSample.m_nReleasingVolumeDivider = 3; + m_sQueueSample.m_fSpeedMultiplier = 2.0f; + break; + case SCRIPT_SOUND_BANK_ALARM_LOOP_L: + m_sQueueSample.m_fSoundIntensity = SCRIPT_OBJECT_INTENSITY_L; + m_sQueueSample.m_nSampleIndex = SFX_BANK_ALARM_1; + m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; + emittingVolume = 90; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_BANK_ALARM_1); + m_sQueueSample.m_nReleasingVolumeModificator = 2; + m_sQueueSample.m_nReleasingVolumeDivider = 3; + m_sQueueSample.m_fSpeedMultiplier = 2.0f; + break; + case SCRIPT_SOUND_POLICE_BALL_LOOP_S: + m_sQueueSample.m_fSoundIntensity = SCRIPT_OBJECT_INTENSITY_S; + m_sQueueSample.m_nSampleIndex = SFX_POLICE_BALL_1; + m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; + emittingVolume = MAX_VOLUME; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_POLICE_BALL_1); + m_sQueueSample.m_nReleasingVolumeModificator = 2; + m_sQueueSample.m_nReleasingVolumeDivider = 3; + m_sQueueSample.m_fSpeedMultiplier = 2.0f; + break; + case SCRIPT_SOUND_POLICE_BALL_LOOP_L: + m_sQueueSample.m_fSoundIntensity = SCRIPT_OBJECT_INTENSITY_L; + m_sQueueSample.m_nSampleIndex = SFX_POLICE_BALL_1; + m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; + emittingVolume = MAX_VOLUME; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_POLICE_BALL_1); + m_sQueueSample.m_nReleasingVolumeModificator = 2; + m_sQueueSample.m_nReleasingVolumeDivider = 3; + m_sQueueSample.m_fSpeedMultiplier = 2.0f; + break; + case SCRIPT_SOUND_RAVE_LOOP_INDUSTRIAL_S: + m_sQueueSample.m_fSoundIntensity = SCRIPT_OBJECT_INTENSITY_S; + m_sQueueSample.m_nSampleIndex = SFX_RAVE_INDUSTRIAL; + m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; + emittingVolume = MAX_VOLUME; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_RAVE_INDUSTRIAL); + m_sQueueSample.m_nReleasingVolumeModificator = 3; + m_sQueueSample.m_nReleasingVolumeDivider = 3; + m_sQueueSample.m_fSpeedMultiplier = 2.0f; + break; + case SCRIPT_SOUND_RAVE_LOOP_INDUSTRIAL_L: + m_sQueueSample.m_fSoundIntensity = SCRIPT_OBJECT_INTENSITY_L; + m_sQueueSample.m_nSampleIndex = SFX_RAVE_INDUSTRIAL; + m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; + emittingVolume = MAX_VOLUME; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_RAVE_INDUSTRIAL); + m_sQueueSample.m_nReleasingVolumeModificator = 3; + m_sQueueSample.m_nReleasingVolumeDivider = 3; + m_sQueueSample.m_fSpeedMultiplier = 2.0f; + break; + case SCRIPT_SOUND_POLICE_CELL_BEATING_LOOP_S: + case SCRIPT_SOUND_POLICE_CELL_BEATING_LOOP_L: + ProcessPoliceCellBeatingScriptObject(sound); + return; + case SCRIPT_SOUND_RAVE_1_LOOP_S: + case SCRIPT_SOUND_RAVE_2_LOOP_S: + m_sQueueSample.m_fSoundIntensity = SCRIPT_OBJECT_INTENSITY_S; + m_sQueueSample.m_nSampleIndex = SFX_RAVE_COMMERCIAL; + m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; + emittingVolume = MAX_VOLUME; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_nReleasingVolumeModificator = 3; + m_sQueueSample.m_nReleasingVolumeDivider = 3; + m_sQueueSample.m_fSpeedMultiplier = 2.0f; + break; + case SCRIPT_SOUND_RAVE_1_LOOP_L: + case SCRIPT_SOUND_RAVE_2_LOOP_L: + m_sQueueSample.m_fSoundIntensity = SCRIPT_OBJECT_INTENSITY_L; + m_sQueueSample.m_nSampleIndex = SFX_RAVE_COMMERCIAL; + m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; + emittingVolume = MAX_VOLUME; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_nReleasingVolumeModificator = 3; + m_sQueueSample.m_nReleasingVolumeDivider = 3; + m_sQueueSample.m_fSpeedMultiplier = 2.0f; + break; + case SCRIPT_SOUND_RAVE_3_LOOP_S: + m_sQueueSample.m_fSoundIntensity = SCRIPT_OBJECT_INTENSITY_S; + m_sQueueSample.m_nSampleIndex = SFX_RAVE_SUBURBAN; + m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; + emittingVolume = MAX_VOLUME; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_RAVE_SUBURBAN); + m_sQueueSample.m_nReleasingVolumeModificator = 3; + m_sQueueSample.m_nReleasingVolumeDivider = 3; + m_sQueueSample.m_fSpeedMultiplier = 2.0f; + break; + case SCRIPT_SOUND_RAVE_3_LOOP_L: + m_sQueueSample.m_fSoundIntensity = SCRIPT_OBJECT_INTENSITY_L; + m_sQueueSample.m_nSampleIndex = SFX_RAVE_SUBURBAN; + m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; + emittingVolume = MAX_VOLUME; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_RAVE_SUBURBAN); + m_sQueueSample.m_nReleasingVolumeModificator = 3; + m_sQueueSample.m_nReleasingVolumeDivider = 3; + m_sQueueSample.m_fSpeedMultiplier = 2.0f; + break; + case SCRIPT_SOUND_PRETEND_FIRE_LOOP: + m_sQueueSample.m_fSoundIntensity = 50.0f; + m_sQueueSample.m_nSampleIndex = SFX_CAR_ON_FIRE; + m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; + emittingVolume = 80; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_CAR_ON_FIRE); + m_sQueueSample.m_nReleasingVolumeModificator = 8; + m_sQueueSample.m_nReleasingVolumeDivider = 10; + m_sQueueSample.m_fSpeedMultiplier = 2.0f; + break; + default: + return; + } + + distSquared = GetDistanceSquared(m_sQueueSample.m_vecPos); + if (distSquared < SQR(m_sQueueSample.m_fSoundIntensity)) { + m_sQueueSample.m_fDistance = Sqrt(distSquared); + m_sQueueSample.m_nVolume = ComputeVolume(emittingVolume, m_sQueueSample.m_fSoundIntensity, m_sQueueSample.m_fDistance); + if (m_sQueueSample.m_nVolume != 0) { + m_sQueueSample.m_nCounter = 0; + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_nLoopCount = 0; + m_sQueueSample.m_bReleasingSoundFlag = false; + m_sQueueSample.m_bReverbFlag = true; + m_sQueueSample.m_nEmittingVolume = emittingVolume; + m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_bRequireReflection = false; + AddSampleToRequestedQueue(); + } + } +} + +void +cAudioManager::ProcessPornCinema(uint8 sound) +{ + + eSfxSample sample; + uint32 time; + int32 rand; + float distSquared; + + switch (sound) { + case SCRIPT_SOUND_PORN_CINEMA_1_S: + case SCRIPT_SOUND_MISTY_SEX_S: + m_sQueueSample.m_nSampleIndex = SFX_PORN_1_LOOP; + m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; + sample = SFX_PORN_1_GROAN_1; + m_sQueueSample.m_fSoundIntensity = 20.0f; + break; + case SCRIPT_SOUND_PORN_CINEMA_1_L: + case SCRIPT_SOUND_MISTY_SEX_L: + m_sQueueSample.m_nSampleIndex = SFX_PORN_1_LOOP; + m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; + sample = SFX_PORN_1_GROAN_1; + m_sQueueSample.m_fSoundIntensity = SCRIPT_OBJECT_INTENSITY_L; + break; + case SCRIPT_SOUND_PORN_CINEMA_2_S: + m_sQueueSample.m_nSampleIndex = SFX_PORN_2_LOOP; + m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; + sample = SFX_PORN_2_GROAN_1; + m_sQueueSample.m_fSoundIntensity = 20.0f; + break; + case SCRIPT_SOUND_PORN_CINEMA_2_L: + m_sQueueSample.m_nSampleIndex = SFX_PORN_2_LOOP; + m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; + sample = SFX_PORN_2_GROAN_1; + m_sQueueSample.m_fSoundIntensity = SCRIPT_OBJECT_INTENSITY_L; + break; + case SCRIPT_SOUND_PORN_CINEMA_3_S: + m_sQueueSample.m_nSampleIndex = SFX_PORN_3_LOOP; + m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; + m_sQueueSample.m_fSoundIntensity = 20.0f; + sample = SFX_PORN_3_GROAN_1; + break; + case SCRIPT_SOUND_PORN_CINEMA_3_L: + m_sQueueSample.m_nSampleIndex = SFX_PORN_3_LOOP; + m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; + m_sQueueSample.m_fSoundIntensity = SCRIPT_OBJECT_INTENSITY_L; + sample = SFX_PORN_3_GROAN_1; + break; + default: + return; + } + distSquared = GetDistanceSquared(m_sQueueSample.m_vecPos); + if (distSquared < SQR(m_sQueueSample.m_fSoundIntensity)) { + m_sQueueSample.m_fDistance = Sqrt(distSquared); + if (sound != SCRIPT_SOUND_MISTY_SEX_S && sound != SCRIPT_SOUND_MISTY_SEX_L) { + m_sQueueSample.m_nVolume = ComputeVolume(MAX_VOLUME, m_sQueueSample.m_fSoundIntensity, m_sQueueSample.m_fDistance); + if (m_sQueueSample.m_nVolume != 0) { + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_nCounter = 0; + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_nLoopCount = 0; + m_sQueueSample.m_bReleasingSoundFlag = false; + m_sQueueSample.m_nReleasingVolumeModificator = 3; + m_sQueueSample.m_fSpeedMultiplier = 2.0f; + m_sQueueSample.m_nEmittingVolume = MAX_VOLUME; + m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_bReverbFlag = true; + m_sQueueSample.m_bRequireReflection = false; + AddSampleToRequestedQueue(); + } + } + + time = CTimer::GetTimeInMilliseconds(); + if (time > gPornNextTime) { + m_sQueueSample.m_nVolume = ComputeVolume(90, m_sQueueSample.m_fSoundIntensity, m_sQueueSample.m_fDistance); + if (m_sQueueSample.m_nVolume != 0) { + rand = m_anRandomTable[1] & 1; + m_sQueueSample.m_nSampleIndex = rand + sample; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_nFrequency += RandomDisplacement(m_sQueueSample.m_nFrequency / 16); + m_sQueueSample.m_nCounter = rand + 1; + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_nLoopCount = 1; + m_sQueueSample.m_bReleasingSoundFlag = true; + m_sQueueSample.m_nReleasingVolumeModificator = 6; + m_sQueueSample.m_fSpeedMultiplier = 0.0f; + m_sQueueSample.m_nLoopStart = 0; + m_sQueueSample.m_nLoopEnd = -1; + m_sQueueSample.m_bReverbFlag = true; + m_sQueueSample.m_bRequireReflection = false; + AddSampleToRequestedQueue(); + gPornNextTime = time + 2000 + m_anRandomTable[3] % 6000; + } + } + } +} + +void +cAudioManager::ProcessWorkShopScriptObject(uint8 sound) +{ + float distSquared; + + switch (sound) { + case SCRIPT_SOUND_WORK_SHOP_LOOP_S: + case SCRIPT_SOUND_WORK_SHOP_LOOP_L: + m_sQueueSample.m_fSoundIntensity = 20.0f; + break; + default: + return; + } + distSquared = GetDistanceSquared(m_sQueueSample.m_vecPos); + if (distSquared < SQR(m_sQueueSample.m_fSoundIntensity)) { + m_sQueueSample.m_fDistance = Sqrt(distSquared); + m_sQueueSample.m_nVolume = ComputeVolume(30, m_sQueueSample.m_fSoundIntensity, m_sQueueSample.m_fDistance); + if (m_sQueueSample.m_nVolume != 0) { + m_sQueueSample.m_nSampleIndex = SFX_WORKSHOP_1; + m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_WORKSHOP_1); + m_sQueueSample.m_nCounter = 0; + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_nLoopCount = 0; + m_sQueueSample.m_bReleasingSoundFlag = false; + m_sQueueSample.m_nReleasingVolumeModificator = 5; + m_sQueueSample.m_fSpeedMultiplier = 2.0f; + m_sQueueSample.m_nEmittingVolume = 30; + m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_bReverbFlag = true; + m_sQueueSample.m_bRequireReflection = false; + AddSampleToRequestedQueue(); + } + } +} + +void +cAudioManager::ProcessSawMillScriptObject(uint8 sound) +{ + + uint32 time; + float distSquared; + + switch (sound) { + case SCRIPT_SOUND_SAWMILL_LOOP_S: + case SCRIPT_SOUND_SAWMILL_LOOP_L: + m_sQueueSample.m_fSoundIntensity = SCRIPT_OBJECT_INTENSITY_S; + break; + default: + return; + } + distSquared = GetDistanceSquared(m_sQueueSample.m_vecPos); + if (distSquared < SQR(m_sQueueSample.m_fSoundIntensity)) { + m_sQueueSample.m_fDistance = Sqrt(distSquared); + m_sQueueSample.m_nVolume = ComputeVolume(30, m_sQueueSample.m_fSoundIntensity, m_sQueueSample.m_fDistance); + if (m_sQueueSample.m_nVolume != 0) { + m_sQueueSample.m_nSampleIndex = SFX_SAWMILL_LOOP; + m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_SAWMILL_LOOP); + m_sQueueSample.m_nCounter = 0; + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_nLoopCount = 0; + m_sQueueSample.m_bReleasingSoundFlag = false; + m_sQueueSample.m_nReleasingVolumeModificator = 5; + m_sQueueSample.m_fSpeedMultiplier = 2.0f; + m_sQueueSample.m_nEmittingVolume = 30; + m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_bReverbFlag = true; + m_sQueueSample.m_bRequireReflection = false; + AddSampleToRequestedQueue(); + } + time = CTimer::GetTimeInMilliseconds(); + if (time > gSawMillNextTime) { + m_sQueueSample.m_nVolume = ComputeVolume(70, m_sQueueSample.m_fSoundIntensity, m_sQueueSample.m_fDistance); + if (m_sQueueSample.m_nVolume != 0) { + m_sQueueSample.m_nSampleIndex = SFX_SAWMILL_CUT_WOOD; + m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_nCounter = 1; + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_nLoopCount = 1; + m_sQueueSample.m_bReleasingSoundFlag = true; + m_sQueueSample.m_nReleasingVolumeModificator = 3; + m_sQueueSample.m_fSpeedMultiplier = 2.0f; + m_sQueueSample.m_nLoopStart = 0; + m_sQueueSample.m_nLoopEnd = -1; + m_sQueueSample.m_bReverbFlag = true; + m_sQueueSample.m_bRequireReflection = false; + AddSampleToRequestedQueue(); + gSawMillNextTime = time + 2000 + m_anRandomTable[3] % 4000; + } + } + } +} + +void +cAudioManager::ProcessLaunderetteScriptObject(uint8 sound) +{ + switch (sound) { + case SCRIPT_SOUND_LAUNDERETTE_LOOP_S: + case SCRIPT_SOUND_LAUNDERETTE_LOOP_L: + m_sQueueSample.m_fSoundIntensity = SCRIPT_OBJECT_INTENSITY_S; + break; + default: + return; + } + float distSquared = GetDistanceSquared(m_sQueueSample.m_vecPos); + if (distSquared < SQR(m_sQueueSample.m_fSoundIntensity)) { + m_sQueueSample.m_fDistance = Sqrt(distSquared); + m_sQueueSample.m_nVolume = ComputeVolume(45, m_sQueueSample.m_fSoundIntensity, m_sQueueSample.m_fDistance); + if (m_sQueueSample.m_nVolume != 0) { + m_sQueueSample.m_nSampleIndex = SFX_LAUNDERETTE_LOOP; + m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_LAUNDERETTE_LOOP); + m_sQueueSample.m_nCounter = 0; + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_nLoopCount = 0; + m_sQueueSample.m_bReleasingSoundFlag = false; + m_sQueueSample.m_nReleasingVolumeModificator = 5; + m_sQueueSample.m_fSpeedMultiplier = 2.0f; + m_sQueueSample.m_nEmittingVolume = 45; + m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_bReverbFlag = true; + m_sQueueSample.m_bRequireReflection = false; + AddSampleToRequestedQueue(); + } + m_sQueueSample.m_nVolume = ComputeVolume(110, m_sQueueSample.m_fSoundIntensity, m_sQueueSample.m_fDistance); + if (m_sQueueSample.m_nVolume != 0) { + m_sQueueSample.m_nSampleIndex = SFX_LAUNDERETTE_SONG_LOOP; + m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_LAUNDERETTE_SONG_LOOP); + m_sQueueSample.m_nCounter = 1; + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_nLoopCount = 0; + m_sQueueSample.m_bReleasingSoundFlag = false; + m_sQueueSample.m_nReleasingVolumeModificator = 3; + m_sQueueSample.m_fSpeedMultiplier = 2.0f; + m_sQueueSample.m_nEmittingVolume = 110; + m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_bReverbFlag = true; + m_sQueueSample.m_bRequireReflection = false; + AddSampleToRequestedQueue(); + } + } +} + +void +cAudioManager::ProcessShopScriptObject(uint8 sound) +{ + uint32 time; + int32 rand; + float distSquared; + + switch (sound) { + case SCRIPT_SOUND_SHOP_LOOP_S: + case SCRIPT_SOUND_SHOP_LOOP_L: + m_sQueueSample.m_fSoundIntensity = SCRIPT_OBJECT_INTENSITY_S; + break; + default: + return; + } + distSquared = GetDistanceSquared(m_sQueueSample.m_vecPos); + if (distSquared < SQR(m_sQueueSample.m_fSoundIntensity)) { + m_sQueueSample.m_fDistance = Sqrt(distSquared); + m_sQueueSample.m_nVolume = ComputeVolume(30, m_sQueueSample.m_fSoundIntensity, m_sQueueSample.m_fDistance); + if (m_sQueueSample.m_nVolume != 0) { + m_sQueueSample.m_nSampleIndex = SFX_SHOP_LOOP; + m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_SHOP_LOOP); + m_sQueueSample.m_nCounter = 0; + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_nLoopCount = 0; + m_sQueueSample.m_bReleasingSoundFlag = false; + m_sQueueSample.m_nReleasingVolumeModificator = 5; + m_sQueueSample.m_fSpeedMultiplier = 2.0f; + m_sQueueSample.m_nEmittingVolume = 30; + m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_bReverbFlag = true; + m_sQueueSample.m_bRequireReflection = false; + AddSampleToRequestedQueue(); + } + time = CTimer::GetTimeInMilliseconds(); + if (time > gShopNextTime) { + m_sQueueSample.m_nVolume = ComputeVolume(70, m_sQueueSample.m_fSoundIntensity, m_sQueueSample.m_fDistance); + if (m_sQueueSample.m_nVolume != 0) { + rand = m_anRandomTable[1] & 1; + m_sQueueSample.m_nSampleIndex = rand + SFX_SHOP_TILL_1; + m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_nCounter = rand + 1; + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_nLoopCount = 1; + m_sQueueSample.m_bReleasingSoundFlag = true; + m_sQueueSample.m_nReleasingVolumeModificator = 3; + m_sQueueSample.m_fSpeedMultiplier = 2.0f; + m_sQueueSample.m_nEmittingVolume = 70; + m_sQueueSample.m_nLoopStart = 0; + m_sQueueSample.m_nLoopEnd = -1; + m_sQueueSample.m_bReverbFlag = true; + m_sQueueSample.m_bRequireReflection = false; + AddSampleToRequestedQueue(); + gShopNextTime = time + 3000 + m_anRandomTable[3] % 7000; + } + } + } +} + +void +cAudioManager::ProcessAirportScriptObject(uint8 sound) +{ + static uint8 iSound = 0; + + uint32 time = CTimer::GetTimeInMilliseconds(); + if (time > gAirportNextTime) { + switch (sound) { + case SCRIPT_SOUND_AIRPORT_LOOP_S: + m_sQueueSample.m_fSoundIntensity = SCRIPT_OBJECT_INTENSITY_S; + break; + case SCRIPT_SOUND_AIRPORT_LOOP_L: + m_sQueueSample.m_fSoundIntensity = SCRIPT_OBJECT_INTENSITY_L; + break; + default: + return; + } + float distSquared = GetDistanceSquared(m_sQueueSample.m_vecPos); + if (distSquared < SQR(m_sQueueSample.m_fSoundIntensity)) { + m_sQueueSample.m_fDistance = Sqrt(distSquared); + m_sQueueSample.m_nVolume = ComputeVolume(110, m_sQueueSample.m_fSoundIntensity, m_sQueueSample.m_fDistance); + if (m_sQueueSample.m_nVolume != 0) { + m_sQueueSample.m_nSampleIndex = (m_anRandomTable[1] & 3) + SFX_AIRPORT_ANNOUNCEMENT_1; + m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_nCounter = iSound++; + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_nLoopCount = 1; + m_sQueueSample.m_bReleasingSoundFlag = true; + m_sQueueSample.m_nReleasingVolumeModificator = 3; + m_sQueueSample.m_fSpeedMultiplier = 2.0f; + m_sQueueSample.m_nEmittingVolume = 110; + m_sQueueSample.m_nLoopStart = 0; + m_sQueueSample.m_nLoopEnd = -1; + m_sQueueSample.m_bReverbFlag = true; + m_sQueueSample.m_bRequireReflection = false; + AddSampleToRequestedQueue(); + gAirportNextTime = time + 10000 + m_anRandomTable[3] % 20000; + } + } + } +} + +void +cAudioManager::ProcessCinemaScriptObject(uint8 sound) +{ + uint8 rand; + + static uint8 iSound = 0; + + uint32 time = CTimer::GetTimeInMilliseconds(); + if (time > gCinemaNextTime) { + switch (sound) { + case SCRIPT_SOUND_CINEMA_LOOP_S: + m_sQueueSample.m_fSoundIntensity = SCRIPT_OBJECT_INTENSITY_S; + break; + case SCRIPT_SOUND_CINEMA_LOOP_L: + m_sQueueSample.m_fSoundIntensity = SCRIPT_OBJECT_INTENSITY_L; + break; + default: + return; + } + float distSquared = GetDistanceSquared(m_sQueueSample.m_vecPos); + if (distSquared < SQR(m_sQueueSample.m_fSoundIntensity)) { + m_sQueueSample.m_fDistance = Sqrt(distSquared); + rand = m_anRandomTable[0] % 90 + 30; + m_sQueueSample.m_nVolume = ComputeVolume(rand, m_sQueueSample.m_fSoundIntensity, m_sQueueSample.m_fDistance); + if (m_sQueueSample.m_nVolume != 0) { + m_sQueueSample.m_nSampleIndex = iSound % 3 + SFX_CINEMA_BASS_1; + m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_nFrequency += RandomDisplacement(m_sQueueSample.m_nFrequency / 4); + m_sQueueSample.m_nCounter = iSound++; + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_nLoopCount = 1; + m_sQueueSample.m_bReleasingSoundFlag = true; + m_sQueueSample.m_nReleasingVolumeModificator = 3; + m_sQueueSample.m_fSpeedMultiplier = 2.0f; + m_sQueueSample.m_nEmittingVolume = rand; + m_sQueueSample.m_nLoopStart = 0; + m_sQueueSample.m_nLoopEnd = -1; + m_sQueueSample.m_bReverbFlag = true; + m_sQueueSample.m_bRequireReflection = false; + AddSampleToRequestedQueue(); + gCinemaNextTime = time + 1000 + m_anRandomTable[3] % 4000; + } + } + } +} + +void +cAudioManager::ProcessDocksScriptObject(uint8 sound) +{ + uint32 time; + uint8 rand; + float distSquared; + + static uint8 iSound = 0; + + time = CTimer::GetTimeInMilliseconds(); + if (time > gDocksNextTime) { + switch (sound) { + case SCRIPT_SOUND_DOCKS_LOOP_S: + m_sQueueSample.m_fSoundIntensity = SCRIPT_OBJECT_INTENSITY_S; + break; + case SCRIPT_SOUND_DOCKS_LOOP_L: + m_sQueueSample.m_fSoundIntensity = SCRIPT_OBJECT_INTENSITY_L; + break; + default: + return; + } + distSquared = GetDistanceSquared(m_sQueueSample.m_vecPos); + if (distSquared < SQR(m_sQueueSample.m_fSoundIntensity)) { + m_sQueueSample.m_fDistance = Sqrt(distSquared); + rand = m_anRandomTable[0] % 60 + 40; + m_sQueueSample.m_nVolume = ComputeVolume(rand, m_sQueueSample.m_fSoundIntensity, m_sQueueSample.m_fDistance); + if (m_sQueueSample.m_nVolume != 0) { + m_sQueueSample.m_nSampleIndex = SFX_DOCKS_FOGHORN; + m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_DOCKS_FOGHORN); + m_sQueueSample.m_nFrequency += RandomDisplacement(m_sQueueSample.m_nFrequency / 8); + m_sQueueSample.m_nCounter = iSound++; + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_nLoopCount = 1; + m_sQueueSample.m_bReleasingSoundFlag = true; + m_sQueueSample.m_nReleasingVolumeModificator = 3; + m_sQueueSample.m_fSpeedMultiplier = 2.0f; + m_sQueueSample.m_nEmittingVolume = rand; + m_sQueueSample.m_nLoopStart = 0; + m_sQueueSample.m_nLoopEnd = -1; + m_sQueueSample.m_bReverbFlag = true; + m_sQueueSample.m_bRequireReflection = false; + AddSampleToRequestedQueue(); + gDocksNextTime = time + 10000 + m_anRandomTable[3] % 40000; + } + } + } +} +void +cAudioManager::ProcessHomeScriptObject(uint8 sound) +{ + uint32 time; + uint8 rand; + float dist; + + static uint8 iSound = 0; + + time = CTimer::GetTimeInMilliseconds(); + if (time > gHomeNextTime) { + switch (sound) { + case SCRIPT_SOUND_HOME_LOOP_S: + m_sQueueSample.m_fSoundIntensity = SCRIPT_OBJECT_INTENSITY_S; + break; + case SCRIPT_SOUND_HOME_LOOP_L: + m_sQueueSample.m_fSoundIntensity = SCRIPT_OBJECT_INTENSITY_L; + break; + default: + return; + } + dist = GetDistanceSquared(m_sQueueSample.m_vecPos); + if (dist < SQR(m_sQueueSample.m_fSoundIntensity)) { + m_sQueueSample.m_fDistance = Sqrt(dist); + rand = m_anRandomTable[0] % 30 + 40; + m_sQueueSample.m_nVolume = ComputeVolume(rand, m_sQueueSample.m_fSoundIntensity, m_sQueueSample.m_fDistance); + if (m_sQueueSample.m_nVolume != 0) { + m_sQueueSample.m_nSampleIndex = m_anRandomTable[0] % 5 + SFX_HOME_1; + m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_nFrequency += RandomDisplacement(m_sQueueSample.m_nFrequency / 16); + m_sQueueSample.m_nCounter = iSound++; + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_nLoopCount = 1; + m_sQueueSample.m_bReleasingSoundFlag = true; + m_sQueueSample.m_nReleasingVolumeModificator = 3; + m_sQueueSample.m_fSpeedMultiplier = 0.0f; + m_sQueueSample.m_nEmittingVolume = rand; + m_sQueueSample.m_nLoopStart = 0; + m_sQueueSample.m_nLoopEnd = -1; + m_sQueueSample.m_bReverbFlag = true; + m_sQueueSample.m_bRequireReflection = true; + AddSampleToRequestedQueue(); + gHomeNextTime = time + 1000 + m_anRandomTable[3] % 4000; + } + } + } +} +void +cAudioManager::ProcessPoliceCellBeatingScriptObject(uint8 sound) +{ + uint32 time = CTimer::GetTimeInMilliseconds(); + int32 sampleIndex; + uint8 emittingVol; + float distSquared; + cPedParams params; + + static uint8 iSound = 0; + + if (time > gCellNextTime) { + switch (sound) { + case SCRIPT_SOUND_POLICE_CELL_BEATING_LOOP_S: + m_sQueueSample.m_fSoundIntensity = SCRIPT_OBJECT_INTENSITY_S; + break; + case SCRIPT_SOUND_POLICE_CELL_BEATING_LOOP_L: + m_sQueueSample.m_fSoundIntensity = SCRIPT_OBJECT_INTENSITY_L; + break; + default: + return; + } + distSquared = GetDistanceSquared(m_sQueueSample.m_vecPos); + if (distSquared < SQR(m_sQueueSample.m_fSoundIntensity)) { + m_sQueueSample.m_fDistance = Sqrt(distSquared); + if (m_FrameCounter & 1) + sampleIndex = (m_anRandomTable[1] & 3) + SFX_FIGHT_1; + else + sampleIndex = (m_anRandomTable[3] & 1) + SFX_BAT_HIT_LEFT; + m_sQueueSample.m_nSampleIndex = sampleIndex; + emittingVol = m_anRandomTable[0] % 50 + 55; + m_sQueueSample.m_nVolume = ComputeVolume(emittingVol, m_sQueueSample.m_fSoundIntensity, m_sQueueSample.m_fDistance); + if (m_sQueueSample.m_nVolume != 0) { + m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_nFrequency += RandomDisplacement(m_sQueueSample.m_nFrequency / 16); + m_sQueueSample.m_nCounter = iSound++; + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_nLoopCount = 1; + m_sQueueSample.m_bReleasingSoundFlag = true; + m_sQueueSample.m_nReleasingVolumeModificator = 3; + m_sQueueSample.m_fSpeedMultiplier = 0.0f; + m_sQueueSample.m_nEmittingVolume = emittingVol; + m_sQueueSample.m_nLoopStart = 0; + m_sQueueSample.m_nLoopEnd = -1; + m_sQueueSample.m_bReverbFlag = true; + m_sQueueSample.m_bRequireReflection = false; + AddSampleToRequestedQueue(); + params.m_bDistanceCalculated = true; + params.m_fDistance = distSquared; + params.m_pPed = nil; + SetupPedComments(¶ms, SOUND_INJURED_PED_MALE_PRISON); + } + gCellNextTime = time + 500 + m_anRandomTable[3] % 1500; + } + } +} +#pragma endregion All the code for script object audio on the map + +void +cAudioManager::ProcessWeather(int32 id) +{ + uint8 vol; + static uint8 iSound = 0; + + if (m_asAudioEntities[id].m_AudioEvents && m_asAudioEntities[id].m_awAudioEvent[0] == SOUND_LIGHTNING) { + if (m_asAudioEntities[id].m_afVolume[0] >= 10.f) { + m_sQueueSample.m_nSampleIndex = SFX_EXPLOSION_1; + m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; + m_sQueueSample.m_nFrequency = RandomDisplacement(500) + 4000; + vol = (m_asAudioEntities[id].m_afVolume[0] - 10.f) + 40; + } else { + m_sQueueSample.m_nSampleIndex = SFX_EXPLOSION_2; + m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; + m_sQueueSample.m_nFrequency = RandomDisplacement(500) + 4000; + vol = (m_asAudioEntities[id].m_afVolume[0]) + 35; + } + m_sQueueSample.m_nVolume = vol; + if (TheCamera.SoundDistUp < 20.f) + m_sQueueSample.m_nVolume /= 2; + if (iSound == 4) + iSound = 0; + m_sQueueSample.m_nCounter = iSound++; + m_sQueueSample.m_nReleasingVolumeModificator = 0; + m_sQueueSample.m_nOffset = (m_anRandomTable[2] & 15) + 55; + m_sQueueSample.m_bIs2D = true; + m_sQueueSample.m_nLoopCount = 1; + m_sQueueSample.m_bReleasingSoundFlag = true; + m_sQueueSample.m_nEmittingVolume = m_sQueueSample.m_nVolume; + m_sQueueSample.m_nLoopStart = 0; + m_sQueueSample.m_nLoopEnd = -1; + m_sQueueSample.m_bReverbFlag = false; + m_sQueueSample.m_bRequireReflection = false; + AddSampleToRequestedQueue(); + } + if (CWeather::Rain > 0.0f && (!CCullZones::CamNoRain() || !CCullZones::PlayerNoRain())) { + m_sQueueSample.m_nSampleIndex = SFX_RAIN; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_RAIN); + m_sQueueSample.m_nVolume = (int32)(25.f * CWeather::Rain); + m_sQueueSample.m_nCounter = 4; + m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; + m_sQueueSample.m_nReleasingVolumeModificator = 0; + m_sQueueSample.m_nOffset = 63; + m_sQueueSample.m_bIs2D = true; + m_sQueueSample.m_nLoopCount = 0; + m_sQueueSample.m_bReleasingSoundFlag = false; + m_sQueueSample.m_nReleasingVolumeDivider = 30; + m_sQueueSample.m_bReverbFlag = false; + m_sQueueSample.m_nEmittingVolume = m_sQueueSample.m_nVolume; + m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_bRequireReflection = false; + AddSampleToRequestedQueue(); + } +} + +void +cAudioManager::ProcessFrontEnd() +{ + bool stereo; + bool processedPickup; + bool processedMission; + int16 sample; + + static uint8 iSound = 0; + static uint32 cPickupNextFrame = 0; + static uint32 cPartMisComNextFrame = 0; + + for (uint32 i = 0; i < m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_AudioEvents; i++) { + processedPickup = false; + stereo = false; + processedMission = false; + switch (m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_awAudioEvent[i]) { + case SOUND_WEAPON_SNIPER_SHOT_NO_ZOOM: + m_sQueueSample.m_nSampleIndex = SFX_ERROR_FIRE_RIFLE; + break; + case SOUND_WEAPON_ROCKET_SHOT_NO_ZOOM: + m_sQueueSample.m_nSampleIndex = SFX_ERROR_FIRE_ROCKET_LAUNCHER; + break; + case SOUND_GARAGE_NO_MONEY: + case SOUND_GARAGE_BAD_VEHICLE: + case SOUND_GARAGE_BOMB_ALREADY_SET: + m_sQueueSample.m_nSampleIndex = SFX_PICKUP_ERROR_LEFT; + stereo = true; + break; + case SOUND_GARAGE_OPENING: + case SOUND_GARAGE_BOMB1_SET: + case SOUND_GARAGE_BOMB2_SET: + case SOUND_GARAGE_BOMB3_SET: + case SOUND_41: + case SOUND_GARAGE_VEHICLE_DECLINED: + case SOUND_GARAGE_VEHICLE_ACCEPTED: + case SOUND_PICKUP_HEALTH: + case SOUND_4B: + case SOUND_PICKUP_ADRENALINE: + case SOUND_PICKUP_ARMOUR: + case SOUND_EVIDENCE_PICKUP: + case SOUND_UNLOAD_GOLD: + m_sQueueSample.m_nSampleIndex = SFX_PICKUP_2_LEFT; + processedPickup = true; + stereo = true; + break; + case SOUND_PICKUP_WEAPON_BOUGHT: + case SOUND_PICKUP_WEAPON: + m_sQueueSample.m_nSampleIndex = SFX_PICKUP_1_LEFT; + processedPickup = true; + stereo = true; + break; + case SOUND_4A: + m_sQueueSample.m_nSampleIndex = SFX_PICKUP_ERROR_LEFT; + processedPickup = true; + stereo = true; + break; + case SOUND_PICKUP_BONUS: + case SOUND_PICKUP_MONEY: + case SOUND_PICKUP_HIDDEN_PACKAGE: + case SOUND_PICKUP_PACMAN_PILL: + case SOUND_PICKUP_PACMAN_PACKAGE: + case SOUND_PICKUP_FLOAT_PACKAGE: + m_sQueueSample.m_nSampleIndex = SFX_PICKUP_3_LEFT; + processedPickup = true; + stereo = true; + break; + case SOUND_PAGER: + m_sQueueSample.m_nSampleIndex = SFX_PAGER; + break; + case SOUND_RACE_START_3: + case SOUND_RACE_START_2: + case SOUND_RACE_START_1: + case SOUND_CLOCK_TICK: + m_sQueueSample.m_nSampleIndex = SFX_TIMER_BEEP; + break; + case SOUND_RACE_START_GO: + m_sQueueSample.m_nSampleIndex = SFX_PART_MISSION_COMPLETE; + break; + case SOUND_PART_MISSION_COMPLETE: + m_sQueueSample.m_nSampleIndex = SFX_PART_MISSION_COMPLETE; + processedMission = true; + break; + case SOUND_FRONTEND_MENU_STARTING: + m_sQueueSample.m_nSampleIndex = SFX_START_BUTTON_LEFT; + stereo = true; + break; + case SOUND_FRONTEND_MENU_COMPLETED: + m_sQueueSample.m_nSampleIndex = SFX_PAGE_CHANGE_AND_BACK_LEFT; + stereo = true; + break; + case SOUND_FRONTEND_MENU_DENIED: + m_sQueueSample.m_nSampleIndex = SFX_HIGHLIGHT_LEFT; + stereo = true; + break; + case SOUND_FRONTEND_MENU_SUCCESS: + m_sQueueSample.m_nSampleIndex = SFX_SELECT_LEFT; + stereo = true; + break; + case SOUND_FRONTEND_EXIT: + m_sQueueSample.m_nSampleIndex = SFX_SUB_MENU_BACK_LEFT; + stereo = true; + break; + case SOUND_9A: + m_sQueueSample.m_nSampleIndex = SFX_STEREO_LEFT; + stereo = true; + break; + case SOUND_9B: + m_sQueueSample.m_nSampleIndex = SFX_MONO; + break; + case SOUND_FRONTEND_AUDIO_TEST: + m_sQueueSample.m_nSampleIndex = m_anRandomTable[0] % 3 + SFX_NOISE_BURST_1; + break; + case SOUND_FRONTEND_FAIL: + m_sQueueSample.m_nSampleIndex = SFX_ERROR_LEFT; + stereo = true; + break; + case SOUND_FRONTEND_NO_RADIO: + case SOUND_FRONTEND_RADIO_CHANGE: + m_sQueueSample.m_nSampleIndex = SFX_RADIO_CLICK; + break; + case SOUND_A0: + m_sQueueSample.m_nSampleIndex = SFX_INFO; + break; + default: + continue; + } + + if (processedPickup) { + if (m_FrameCounter <= cPickupNextFrame) + continue; + cPickupNextFrame = m_FrameCounter + 5; + } else if (processedMission) { + if (m_FrameCounter <= cPartMisComNextFrame) + continue; + cPartMisComNextFrame = m_FrameCounter + 5; + } + + sample = m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_awAudioEvent[i]; + if (sample == SFX_RAIN) { + m_sQueueSample.m_nFrequency = 28509; + } else if (sample == SFX_PICKUP_1_LEFT) { + if (m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_afVolume[i] == 1.0f) + m_sQueueSample.m_nFrequency = 32000; + else + m_sQueueSample.m_nFrequency = 48000; + } else { + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(m_sQueueSample.m_nSampleIndex); + } + m_sQueueSample.m_nVolume = 110; + m_sQueueSample.m_nCounter = iSound++; + m_sQueueSample.m_nLoopCount = 1; + m_sQueueSample.m_bReleasingSoundFlag = true; + m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; + m_sQueueSample.m_nReleasingVolumeModificator = 0; + m_sQueueSample.m_bIs2D = true; + m_sQueueSample.m_nEmittingVolume = m_sQueueSample.m_nVolume; + m_sQueueSample.m_nLoopStart = 0; + m_sQueueSample.m_nLoopEnd = -1; + if (stereo) + m_sQueueSample.m_nOffset = m_anRandomTable[0] & 31; + else + m_sQueueSample.m_nOffset = 63; + m_sQueueSample.m_bReverbFlag = false; + m_sQueueSample.m_bRequireReflection = false; + AddSampleToRequestedQueue(); + if (stereo) { + ++m_sQueueSample.m_nSampleIndex; + m_sQueueSample.m_nCounter = iSound++; + m_sQueueSample.m_nOffset = MAX_VOLUME - m_sQueueSample.m_nOffset; + AddSampleToRequestedQueue(); + } + } +} + +void +cAudioManager::ProcessCrane() +{ + CCrane *crane = (CCrane *)m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_pEntity; + float distSquared; + bool distCalculated = false; + static const int intensity = 80; + + if (crane) { + if (crane->m_nCraneStatus == CCrane::ACTIVATED) { + if (crane->m_nCraneState != CCrane::IDLE) { + m_sQueueSample.m_vecPos = crane->m_pCraneEntity->GetPosition(); + distSquared = GetDistanceSquared(m_sQueueSample.m_vecPos); + if (distSquared < SQR(intensity)) { + CalculateDistance(distCalculated, distSquared); + m_sQueueSample.m_nVolume = ComputeVolume(100, 80.f, m_sQueueSample.m_fDistance); + if (m_sQueueSample.m_nVolume != 0) { + m_sQueueSample.m_nCounter = 0; + m_sQueueSample.m_nSampleIndex = SFX_CRANE_MAGNET; + m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_nReleasingVolumeModificator = 2; + m_sQueueSample.m_nFrequency = 6000; + m_sQueueSample.m_nLoopCount = 0; + m_sQueueSample.m_nEmittingVolume = 100; + m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_fSpeedMultiplier = 4.0f; + m_sQueueSample.m_fSoundIntensity = intensity; + m_sQueueSample.m_bReleasingSoundFlag = false; + m_sQueueSample.m_nReleasingVolumeDivider = 3; + m_sQueueSample.m_bReverbFlag = true; + m_sQueueSample.m_bRequireReflection = false; + AddSampleToRequestedQueue(); + } + if (m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_AudioEvents) { + m_sQueueSample.m_nCounter = 1; + m_sQueueSample.m_nSampleIndex = SFX_COL_CAR_2; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_COL_CAR_2); + m_sQueueSample.m_nLoopCount = 1; + m_sQueueSample.m_bReleasingSoundFlag = true; + m_sQueueSample.m_bReverbFlag = true; + m_sQueueSample.m_bRequireReflection = true; + AddSampleToRequestedQueue(); + } + } + } + } + } +} + +void +cAudioManager::ProcessProjectiles() +{ + const int rocketLauncherIntensity = 90; + const int molotovIntensity = 30; + const int molotovVolume = 50; + uint8 emittingVol; + + for (int32 i = 0; i < NUM_PROJECTILES; i++) { + if (CProjectileInfo::GetProjectileInfo(i)->m_bInUse) { + switch (CProjectileInfo::GetProjectileInfo(i)->m_eWeaponType) { + case WEAPONTYPE_ROCKETLAUNCHER: + emittingVol = MAX_VOLUME; + m_sQueueSample.m_fSoundIntensity = rocketLauncherIntensity; + m_sQueueSample.m_nSampleIndex = SFX_ROCKET_FLY; + m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_ROCKET_FLY); + m_sQueueSample.m_nReleasingVolumeModificator = 3; + break; + case WEAPONTYPE_MOLOTOV: + emittingVol = molotovVolume; + m_sQueueSample.m_fSoundIntensity = molotovIntensity; + m_sQueueSample.m_nSampleIndex = SFX_PED_ON_FIRE; + m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; + m_sQueueSample.m_nFrequency = 32 * SampleManager.GetSampleBaseFrequency(SFX_PED_ON_FIRE) / 25; + m_sQueueSample.m_nReleasingVolumeModificator = 7; + break; + default: + return; + } + m_sQueueSample.m_fSpeedMultiplier = 4.0f; + m_sQueueSample.m_nReleasingVolumeDivider = 3; + m_sQueueSample.m_vecPos = CProjectileInfo::ms_apProjectile[i]->GetPosition(); + float distSquared = GetDistanceSquared(m_sQueueSample.m_vecPos); + if (distSquared < SQR(m_sQueueSample.m_fSoundIntensity)) { + m_sQueueSample.m_fDistance = Sqrt(distSquared); + m_sQueueSample.m_nVolume = ComputeVolume(emittingVol, m_sQueueSample.m_fSoundIntensity, m_sQueueSample.m_fDistance); + if (m_sQueueSample.m_nVolume != 0) { + m_sQueueSample.m_nCounter = i; + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_nLoopCount = 0; + m_sQueueSample.m_nEmittingVolume = emittingVol; + m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_bReleasingSoundFlag = false; + m_sQueueSample.m_bReverbFlag = true; + m_sQueueSample.m_bRequireReflection = false; + AddSampleToRequestedQueue(); + } + } + } + } +} + +void +cAudioManager::ProcessGarages() +{ + const float SOUND_INTENSITY = 80.0f; + + CEntity *entity; + eGarageState state; + uint32 sampleIndex; + uint8 j; + float distSquared; + bool distCalculated; + + static uint8 iSound = 32; + + for (uint32 i = 0; i < CGarages::NumGarages; ++i) { + if (CGarages::aGarages[i].m_eGarageType == GARAGE_NONE) + continue; + entity = CGarages::aGarages[i].m_pDoor1; + if (entity == nil) + continue; + m_sQueueSample.m_vecPos = entity->GetPosition(); + distCalculated = false; + distSquared = GetDistanceSquared(m_sQueueSample.m_vecPos); + if (distSquared < SQR(SOUND_INTENSITY)) { + state = CGarages::aGarages[i].m_eGarageState; + // while is here just to exit prematurely and avoid goto + while (state == GS_OPENING || state == GS_CLOSING || state == GS_AFTERDROPOFF) { + CalculateDistance(distCalculated, distSquared); + m_sQueueSample.m_nVolume = ComputeVolume(90, SOUND_INTENSITY, m_sQueueSample.m_fDistance); + if (m_sQueueSample.m_nVolume != 0) { + if (CGarages::aGarages[i].m_eGarageType == GARAGE_CRUSHER) { + if (CGarages::aGarages[i].m_eGarageState == GS_AFTERDROPOFF) { + if (m_FrameCounter & 1) { + if (m_anRandomTable[1] & 1) + sampleIndex = m_anRandomTable[2] % 5 + SFX_COL_CAR_1; + else + sampleIndex = m_anRandomTable[2] % 6 + SFX_COL_CAR_PANEL_1; + m_sQueueSample.m_nSampleIndex = sampleIndex; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(m_sQueueSample.m_nSampleIndex) / 2; + m_sQueueSample.m_nFrequency += RandomDisplacement(m_sQueueSample.m_nFrequency / 16); + m_sQueueSample.m_nLoopCount = 1; + m_sQueueSample.m_bReleasingSoundFlag = true; + m_sQueueSample.m_nCounter = iSound++; + if (iSound < 32) + iSound = 32; + } else break; // premature exit to go straight to the for loop + } else { + m_sQueueSample.m_nSampleIndex = SFX_FISHING_BOAT_IDLE; + m_sQueueSample.m_nFrequency = 6543; + + m_sQueueSample.m_nCounter = i; + m_sQueueSample.m_nLoopCount = 0; + m_sQueueSample.m_nReleasingVolumeDivider = 3; + m_sQueueSample.m_bReleasingSoundFlag = false; + } + } else { + m_sQueueSample.m_nSampleIndex = SFX_GARAGE_DOOR_LOOP; + m_sQueueSample.m_nFrequency = 13961; + + m_sQueueSample.m_nCounter = i; + m_sQueueSample.m_nLoopCount = 0; + m_sQueueSample.m_nReleasingVolumeDivider = 3; + m_sQueueSample.m_bReleasingSoundFlag = false; + } + + m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_nReleasingVolumeModificator = 3; + m_sQueueSample.m_nEmittingVolume = 90; + m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_fSpeedMultiplier = 2.0f; + m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY; + m_sQueueSample.m_bReverbFlag = true; + m_sQueueSample.m_bRequireReflection = false; + AddSampleToRequestedQueue(); + } + break; + } + } + for (j = 0; j < m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_AudioEvents; ++j) { + switch (m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_awAudioEvent[j]) { + case SOUND_GARAGE_DOOR_CLOSED: + case SOUND_GARAGE_DOOR_OPENED: + if (distSquared < SQR(SOUND_INTENSITY)) { + CalculateDistance(distCalculated, distSquared); + m_sQueueSample.m_nVolume = ComputeVolume(60, SOUND_INTENSITY, m_sQueueSample.m_fDistance); + if (m_sQueueSample.m_nVolume != 0) { + if (CGarages::aGarages[i].m_eGarageType == GARAGE_CRUSHER) { + m_sQueueSample.m_nSampleIndex = SFX_COL_CAR_PANEL_2; + m_sQueueSample.m_nFrequency = 6735; + } else if (m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_awAudioEvent[j] == SOUND_GARAGE_DOOR_OPENED) { + m_sQueueSample.m_nSampleIndex = SFX_COL_CAR_PANEL_2; + m_sQueueSample.m_nFrequency = 22000; + } else { + m_sQueueSample.m_nSampleIndex = SFX_COL_GARAGE_DOOR_1; + m_sQueueSample.m_nFrequency = 18000; + } + m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; + m_sQueueSample.m_nReleasingVolumeModificator = 4; + m_sQueueSample.m_nEmittingVolume = 60; + m_sQueueSample.m_fSpeedMultiplier = 0.0f; + m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY; + m_sQueueSample.m_bReverbFlag = true; + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_bReleasingSoundFlag = true; + m_sQueueSample.m_nLoopCount = 1; + m_sQueueSample.m_nLoopStart = 0; + m_sQueueSample.m_nLoopEnd = -1; + m_sQueueSample.m_nCounter = iSound++; + if (iSound < 32) + iSound = 32; + m_sQueueSample.m_bRequireReflection = true; + AddSampleToRequestedQueue(); + } + } + break; + default: + break; + } + } + } +} + +void +cAudioManager::ProcessFireHydrant() +{ + float distSquared; + bool distCalculated = false; + static const int intensity = 35; + + m_sQueueSample.m_vecPos = ((CEntity *)m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_pEntity)->GetPosition(); + distSquared = GetDistanceSquared(m_sQueueSample.m_vecPos); + if (distSquared < SQR(intensity)) { + CalculateDistance(distCalculated, distSquared); + m_sQueueSample.m_nVolume = ComputeVolume(40, 35.f, m_sQueueSample.m_fDistance); + if (m_sQueueSample.m_nVolume != 0) { + m_sQueueSample.m_nCounter = 0; + m_sQueueSample.m_nSampleIndex = SFX_JUMBO_TAXI; + m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_nReleasingVolumeModificator = 4; + m_sQueueSample.m_nFrequency = 15591; + m_sQueueSample.m_nLoopCount = 0; + m_sQueueSample.m_nEmittingVolume = 40; + m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_fSpeedMultiplier = 2.0f; + m_sQueueSample.m_fSoundIntensity = intensity; + m_sQueueSample.m_bReleasingSoundFlag = false; + m_sQueueSample.m_nReleasingVolumeDivider = 3; + m_sQueueSample.m_bReverbFlag = true; + m_sQueueSample.m_bRequireReflection = false; + AddSampleToRequestedQueue(); + } + } +} + +#pragma region BRIDGE +const int bridgeIntensity = 400; + +void +cAudioManager::ProcessBridge() +{ + float dist; + bool distCalculated = false; + + if (CBridge::pLiftRoad) { + m_sQueueSample.m_vecPos = CBridge::pLiftRoad->GetPosition(); + dist = GetDistanceSquared(m_sQueueSample.m_vecPos); + if (dist < SQR(450.0f)) { + CalculateDistance(distCalculated, dist); + switch (CBridge::State) { + case STATE_BRIDGE_LOCKED: + case STATE_LIFT_PART_IS_UP: + case STATE_LIFT_PART_ABOUT_TO_MOVE_UP: + ProcessBridgeWarning(); + break; + case STATE_LIFT_PART_MOVING_DOWN: + case STATE_LIFT_PART_MOVING_UP: + ProcessBridgeWarning(); + ProcessBridgeMotor(); + break; + default: + break; + } + ProcessBridgeOneShots(); + } + } +} + +void +cAudioManager::ProcessBridgeWarning() +{ + if (CStats::CommercialPassed && m_sQueueSample.m_fDistance < 450.f) { + m_sQueueSample.m_nVolume = ComputeVolume(100, 450.f, m_sQueueSample.m_fDistance); + if (m_sQueueSample.m_nVolume != 0) { + m_sQueueSample.m_nCounter = 0; + m_sQueueSample.m_nSampleIndex = SFX_BRIDGE_OPEN_WARNING; + m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_nReleasingVolumeModificator = 1; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_BRIDGE_OPEN_WARNING); + m_sQueueSample.m_nLoopCount = 0; + m_sQueueSample.m_nEmittingVolume = 100; + m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_fSpeedMultiplier = 2.0f; + m_sQueueSample.m_fSoundIntensity = 450.0f; + m_sQueueSample.m_bReleasingSoundFlag = false; + m_sQueueSample.m_nReleasingVolumeDivider = 8; + m_sQueueSample.m_bReverbFlag = false; + m_sQueueSample.m_bRequireReflection = false; + AddSampleToRequestedQueue(); + } + } +} + +void +cAudioManager::ProcessBridgeMotor() +{ + if (m_sQueueSample.m_fDistance < bridgeIntensity) { + m_sQueueSample.m_nVolume = ComputeVolume(MAX_VOLUME, bridgeIntensity, m_sQueueSample.m_fDistance); + if (m_sQueueSample.m_nVolume != 0) { + m_sQueueSample.m_nCounter = 1; + m_sQueueSample.m_nSampleIndex = SFX_FISHING_BOAT_IDLE; // todo check sfx name + m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_nReleasingVolumeModificator = 1; + m_sQueueSample.m_nFrequency = 5500; + m_sQueueSample.m_nLoopCount = 0; + m_sQueueSample.m_nEmittingVolume = MAX_VOLUME; + m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_fSpeedMultiplier = 2.0f; + m_sQueueSample.m_fSoundIntensity = bridgeIntensity; + m_sQueueSample.m_bReleasingSoundFlag = false; + m_sQueueSample.m_nReleasingVolumeDivider = 3; + m_sQueueSample.m_bReverbFlag = false; + AddSampleToRequestedQueue(); + } + } +} + +void +cAudioManager::ProcessBridgeOneShots() +{ + if (CBridge::State == STATE_LIFT_PART_IS_UP && CBridge::OldState == STATE_LIFT_PART_MOVING_UP) + m_sQueueSample.m_nSampleIndex = SFX_COL_CONTAINER_1; + else if (CBridge::State == STATE_LIFT_PART_IS_DOWN && CBridge::OldState == STATE_LIFT_PART_MOVING_DOWN) + m_sQueueSample.m_nSampleIndex = SFX_COL_CONTAINER_1; + else if (CBridge::State == STATE_LIFT_PART_MOVING_UP && CBridge::OldState == STATE_LIFT_PART_ABOUT_TO_MOVE_UP) + m_sQueueSample.m_nSampleIndex = SFX_COL_CONTAINER_1; + else if (CBridge::State == STATE_LIFT_PART_MOVING_DOWN && CBridge::OldState == STATE_LIFT_PART_IS_UP) + m_sQueueSample.m_nSampleIndex = SFX_COL_CONTAINER_1; + else return; + + if (m_sQueueSample.m_fDistance < bridgeIntensity) { + m_sQueueSample.m_nVolume = ComputeVolume(MAX_VOLUME, bridgeIntensity, m_sQueueSample.m_fDistance); + if (m_sQueueSample.m_nVolume != 0) { + m_sQueueSample.m_nCounter = 2; + m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_nReleasingVolumeModificator = 1; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_nLoopCount = 1; + m_sQueueSample.m_nEmittingVolume = MAX_VOLUME; + m_sQueueSample.m_nLoopStart = 0; + m_sQueueSample.m_nLoopEnd = -1; + m_sQueueSample.m_fSpeedMultiplier = 2.0f; + m_sQueueSample.m_fSoundIntensity = bridgeIntensity; + m_sQueueSample.m_bReleasingSoundFlag = true; + m_sQueueSample.m_bReverbFlag = false; + m_sQueueSample.m_bRequireReflection = false; + AddSampleToRequestedQueue(); + } + } +} +#pragma endregion + +#pragma region MISSION_AUDIO +bool g_bMissionAudioLoadFailed; + +struct MissionAudioData { + const char *m_pName; + int32 m_nId; +}; + +const MissionAudioData MissionAudioNameSfxAssoc[] = { + {"lib_a1", STREAMED_SOUND_MISSION_LIB_A1}, {"lib_a2", STREAMED_SOUND_MISSION_LIB_A2}, {"lib_a", STREAMED_SOUND_MISSION_LIB_A}, + {"lib_b", STREAMED_SOUND_MISSION_LIB_B}, {"lib_c", STREAMED_SOUND_MISSION_LIB_C}, {"lib_d", STREAMED_SOUND_MISSION_LIB_D}, + {"l2_a", STREAMED_SOUND_MISSION_L2_A}, {"j4t_1", STREAMED_SOUND_MISSION_J4T_1}, {"j4t_2", STREAMED_SOUND_MISSION_J4T_2}, + {"j4t_3", STREAMED_SOUND_MISSION_J4T_3}, {"j4t_4", STREAMED_SOUND_MISSION_J4T_4}, {"j4_a", STREAMED_SOUND_MISSION_J4_A}, + {"j4_b", STREAMED_SOUND_MISSION_J4_B}, {"j4_c", STREAMED_SOUND_MISSION_J4_C}, {"j4_d", STREAMED_SOUND_MISSION_J4_D}, + {"j4_e", STREAMED_SOUND_MISSION_J4_E}, {"j4_f", STREAMED_SOUND_MISSION_J4_F}, {"j6_1", STREAMED_SOUND_MISSION_J6_1}, + {"j6_a", STREAMED_SOUND_MISSION_J6_A}, {"j6_b", STREAMED_SOUND_MISSION_J6_B}, {"j6_c", STREAMED_SOUND_MISSION_J6_C}, + {"j6_d", STREAMED_SOUND_MISSION_J6_D}, {"t4_a", STREAMED_SOUND_MISSION_T4_A}, {"s1_a", STREAMED_SOUND_MISSION_S1_A}, + {"s1_a1", STREAMED_SOUND_MISSION_S1_A1}, {"s1_b", STREAMED_SOUND_MISSION_S1_B}, {"s1_c", STREAMED_SOUND_MISSION_S1_C}, + {"s1_c1", STREAMED_SOUND_MISSION_S1_C1}, {"s1_d", STREAMED_SOUND_MISSION_S1_D}, {"s1_e", STREAMED_SOUND_MISSION_S1_E}, + {"s1_f", STREAMED_SOUND_MISSION_S1_F}, {"s1_g", STREAMED_SOUND_MISSION_S1_G}, {"s1_h", STREAMED_SOUND_MISSION_S1_H}, + {"s1_i", STREAMED_SOUND_MISSION_S1_I}, {"s1_j", STREAMED_SOUND_MISSION_S1_J}, {"s1_k", STREAMED_SOUND_MISSION_S1_K}, + {"s1_l", STREAMED_SOUND_MISSION_S1_L}, {"s3_a", STREAMED_SOUND_MISSION_S3_A}, {"s3_b", STREAMED_SOUND_MISSION_S3_B}, + {"el3_a", STREAMED_SOUND_MISSION_EL3_A}, {"mf1_a", STREAMED_SOUND_MISSION_MF1_A}, {"mf2_a", STREAMED_SOUND_MISSION_MF2_A}, + {"mf3_a", STREAMED_SOUND_MISSION_MF3_A}, {"mf3_b", STREAMED_SOUND_MISSION_MF3_B}, {"mf3_b1", STREAMED_SOUND_MISSION_MF3_B1}, + {"mf3_c", STREAMED_SOUND_MISSION_MF3_C}, {"mf4_a", STREAMED_SOUND_MISSION_MF4_A}, {"mf4_b", STREAMED_SOUND_MISSION_MF4_B}, + {"mf4_c", STREAMED_SOUND_MISSION_MF4_C}, {"a1_a", STREAMED_SOUND_MISSION_A1_A}, {"a3_a", STREAMED_SOUND_MISSION_A3_A}, + {"a5_a", STREAMED_SOUND_MISSION_A5_A}, {"a4_a", STREAMED_SOUND_MISSION_A4_A}, {"a4_b", STREAMED_SOUND_MISSION_A4_B}, + {"a4_c", STREAMED_SOUND_MISSION_A4_C}, {"a4_d", STREAMED_SOUND_MISSION_A4_D}, {"k1_a", STREAMED_SOUND_MISSION_K1_A}, + {"k3_a", STREAMED_SOUND_MISSION_K3_A}, {"r1_a", STREAMED_SOUND_MISSION_R1_A}, {"r2_a", STREAMED_SOUND_MISSION_R2_A}, + {"r2_b", STREAMED_SOUND_MISSION_R2_B}, {"r2_c", STREAMED_SOUND_MISSION_R2_C}, {"r2_d", STREAMED_SOUND_MISSION_R2_D}, + {"r2_e", STREAMED_SOUND_MISSION_R2_E}, {"r2_f", STREAMED_SOUND_MISSION_R2_F}, {"r2_g", STREAMED_SOUND_MISSION_R2_G}, + {"r2_h", STREAMED_SOUND_MISSION_R2_H}, {"r5_a", STREAMED_SOUND_MISSION_R5_A}, {"r6_a", STREAMED_SOUND_MISSION_R6_A}, + {"r6_a1", STREAMED_SOUND_MISSION_R6_A1}, {"r6_b", STREAMED_SOUND_MISSION_R6_B}, {"lo2_a", STREAMED_SOUND_MISSION_LO2_A}, + {"lo6_a", STREAMED_SOUND_MISSION_LO6_A}, {"yd2_a", STREAMED_SOUND_MISSION_YD2_A}, {"yd2_b", STREAMED_SOUND_MISSION_YD2_B}, + {"yd2_c", STREAMED_SOUND_MISSION_YD2_C}, {"yd2_c1", STREAMED_SOUND_MISSION_YD2_C1}, {"yd2_d", STREAMED_SOUND_MISSION_YD2_D}, + {"yd2_e", STREAMED_SOUND_MISSION_YD2_E}, {"yd2_f", STREAMED_SOUND_MISSION_YD2_F}, {"yd2_g", STREAMED_SOUND_MISSION_YD2_G}, + {"yd2_h", STREAMED_SOUND_MISSION_YD2_H}, {"yd2_ass", STREAMED_SOUND_MISSION_YD2_ASS}, {"yd2_ok", STREAMED_SOUND_MISSION_YD2_OK}, + {"h5_a", STREAMED_SOUND_MISSION_H5_A}, {"h5_b", STREAMED_SOUND_MISSION_H5_B}, {"h5_c", STREAMED_SOUND_MISSION_H5_C}, + {"ammu_a", STREAMED_SOUND_MISSION_AMMU_A}, {"ammu_b", STREAMED_SOUND_MISSION_AMMU_B}, {"ammu_c", STREAMED_SOUND_MISSION_AMMU_C}, + {"door_1", STREAMED_SOUND_MISSION_DOOR_1}, {"door_2", STREAMED_SOUND_MISSION_DOOR_2}, {"door_3", STREAMED_SOUND_MISSION_DOOR_3}, + {"door_4", STREAMED_SOUND_MISSION_DOOR_4}, {"door_5", STREAMED_SOUND_MISSION_DOOR_5}, {"door_6", STREAMED_SOUND_MISSION_DOOR_6}, + {"t3_a", STREAMED_SOUND_MISSION_T3_A}, {"t3_b", STREAMED_SOUND_MISSION_T3_B}, {"t3_c", STREAMED_SOUND_MISSION_T3_C}, + {"k1_b", STREAMED_SOUND_MISSION_K1_B}, {"c_1", STREAMED_SOUND_MISSION_CAT1}}; + +int32 +FindMissionAudioSfx(const char *name) +{ + for (uint32 i = 0; i < ARRAY_SIZE(MissionAudioNameSfxAssoc); ++i) { + if (!CGeneral::faststricmp(MissionAudioNameSfxAssoc[i].m_pName, name)) + return MissionAudioNameSfxAssoc[i].m_nId; + } + debug("Can't find mission audio %s", name); + return NO_SAMPLE; +} + +bool +cAudioManager::MissionScriptAudioUsesPoliceChannel(int32 soundMission) const +{ + switch (soundMission) { + case STREAMED_SOUND_MISSION_J6_D: + case STREAMED_SOUND_MISSION_T4_A: + case STREAMED_SOUND_MISSION_S1_H: + case STREAMED_SOUND_MISSION_S3_B: + case STREAMED_SOUND_MISSION_EL3_A: + case STREAMED_SOUND_MISSION_A3_A: + case STREAMED_SOUND_MISSION_A5_A: + case STREAMED_SOUND_MISSION_K1_A: + case STREAMED_SOUND_MISSION_R1_A: + case STREAMED_SOUND_MISSION_R5_A: + case STREAMED_SOUND_MISSION_LO2_A: + case STREAMED_SOUND_MISSION_LO6_A: + return true; + default: + return false; + } +} + +void +cAudioManager::PreloadMissionAudio(const char *name) +{ + if (m_bIsInitialised) { + int32 missionAudioSfx = FindMissionAudioSfx(name); + if (missionAudioSfx != NO_SAMPLE) { + m_sMissionAudio.m_nSampleIndex = missionAudioSfx; + m_sMissionAudio.m_nLoadingStatus = LOADING_STATUS_NOT_LOADED; + m_sMissionAudio.m_nPlayStatus = PLAY_STATUS_STOPPED; + m_sMissionAudio.field_22 = 0; + m_sMissionAudio.m_nMissionAudioCounter = m_nTimeSpent * SampleManager.GetStreamedFileLength(missionAudioSfx) / 1000; + m_sMissionAudio.m_nMissionAudioCounter *= 4; + m_sMissionAudio.m_bIsPlayed = false; + m_sMissionAudio.m_bPredefinedProperties = 1; + g_bMissionAudioLoadFailed = false; + } + } +} + +uint8 +cAudioManager::GetMissionAudioLoadingStatus() const +{ + if (m_bIsInitialised) + return m_sMissionAudio.m_nLoadingStatus; + + return LOADING_STATUS_LOADED; +} + +void +cAudioManager::SetMissionAudioLocation(float x, float y, float z) +{ + if (m_bIsInitialised) { + m_sMissionAudio.m_bPredefinedProperties = false; + m_sMissionAudio.m_vecPos = CVector(x, y, z); + } +} + +void +cAudioManager::PlayLoadedMissionAudio() +{ + if (m_bIsInitialised && m_sMissionAudio.m_nSampleIndex != NO_SAMPLE && m_sMissionAudio.m_nLoadingStatus == LOADING_STATUS_LOADED && + m_sMissionAudio.m_nPlayStatus == PLAY_STATUS_STOPPED) + m_sMissionAudio.m_bIsPlayed = true; +} + +bool +cAudioManager::IsMissionAudioSampleFinished() +{ + if (m_bIsInitialised) + return m_sMissionAudio.m_nPlayStatus == PLAY_STATUS_FINISHED; + + static int32 cPretendFrame = 1; + + return (cPretendFrame++ & 63) == 0; +} + +void +cAudioManager::ClearMissionAudio() +{ + if (m_bIsInitialised) { + m_sMissionAudio.m_nSampleIndex = NO_SAMPLE; + m_sMissionAudio.m_nLoadingStatus = LOADING_STATUS_NOT_LOADED; + m_sMissionAudio.m_nPlayStatus = PLAY_STATUS_STOPPED; + m_sMissionAudio.field_22 = 0; + m_sMissionAudio.m_bIsPlayed = false; + m_sMissionAudio.m_bPredefinedProperties = true; + m_sMissionAudio.m_nMissionAudioCounter = 0; + } +} + +void +cAudioManager::ProcessMissionAudio() +{ + float dist; + uint8 emittingVol; + uint8 pan; + float distSquared; + CVector vec; + + static uint8 nCheckPlayingDelay = 0; + static uint8 nFramesUntilFailedLoad = 0; + static uint8 nFramesForPretendPlaying = 0; + + if (!m_bIsInitialised) return; + if (m_sMissionAudio.m_nSampleIndex == NO_SAMPLE) return; + + switch (m_sMissionAudio.m_nLoadingStatus) { + case LOADING_STATUS_NOT_LOADED: + SampleManager.PreloadStreamedFile(m_sMissionAudio.m_nSampleIndex, 1); + m_sMissionAudio.m_nLoadingStatus = LOADING_STATUS_LOADED; + nFramesUntilFailedLoad = 0; + break; + case LOADING_STATUS_LOADED: + if (!m_sMissionAudio.m_bIsPlayed) + return; + if (g_bMissionAudioLoadFailed) { + if (m_bTimerJustReset) { + ClearMissionAudio(); + SampleManager.StopStreamedFile(1); + nFramesForPretendPlaying = 0; + nCheckPlayingDelay = 0; + nFramesUntilFailedLoad = 0; + } else if (!m_nUserPause) { + if (++nFramesForPretendPlaying < 120) { + m_sMissionAudio.m_nPlayStatus = PLAY_STATUS_PLAYING; + } else { + m_sMissionAudio.m_nPlayStatus = PLAY_STATUS_FINISHED; + m_sMissionAudio.m_nSampleIndex = NO_SAMPLE; + } + } + break; + } + switch (m_sMissionAudio.m_nPlayStatus) { + case PLAY_STATUS_STOPPED: + if (MissionScriptAudioUsesPoliceChannel(m_sMissionAudio.m_nSampleIndex)) { + SetMissionScriptPoliceAudio(m_sMissionAudio.m_nSampleIndex); + } else { + if (m_nUserPause) + SampleManager.PauseStream(1, 1); + if (m_sMissionAudio.m_bPredefinedProperties) { + SampleManager.SetStreamedVolumeAndPan(80, 63, 1, 1); + } else { + distSquared = GetDistanceSquared(m_sMissionAudio.m_vecPos); + if (distSquared >= SQR(50.0f)) { + emittingVol = 0; + pan = 63; + } else { + dist = Sqrt(distSquared); + emittingVol = ComputeVolume(80, 50.0f, dist); + TranslateEntity(&m_sMissionAudio.m_vecPos, &vec); + pan = ComputePan(50.f, &vec); + } + SampleManager.SetStreamedVolumeAndPan(emittingVol, pan, 1, 1); + } + SampleManager.StartPreloadedStreamedFile(1); + } + m_sMissionAudio.m_nPlayStatus = PLAY_STATUS_PLAYING; + nCheckPlayingDelay = 30; + break; + case PLAY_STATUS_PLAYING: + if (m_bTimerJustReset) { + ClearMissionAudio(); + SampleManager.StopStreamedFile(1); + break; + } + if (MissionScriptAudioUsesPoliceChannel(m_sMissionAudio.m_nSampleIndex)) { + if (!m_nUserPause) { + if (nCheckPlayingDelay) { + --nCheckPlayingDelay; + } else if (GetMissionScriptPoliceAudioPlayingStatus() == PLAY_STATUS_FINISHED || m_sMissionAudio.m_nMissionAudioCounter-- == 0) { + m_sMissionAudio.m_nPlayStatus = PLAY_STATUS_FINISHED; + m_sMissionAudio.m_nSampleIndex = NO_SAMPLE; + SampleManager.StopStreamedFile(1); + m_sMissionAudio.m_nMissionAudioCounter = 0; + } + } + } else if (m_sMissionAudio.field_22) { + if (SampleManager.IsStreamPlaying(1) || m_nUserPause || m_nPreviousUserPause) { + if (m_nUserPause) + SampleManager.PauseStream(1, 1); + else + SampleManager.PauseStream(0, 1); + } else { + m_sMissionAudio.m_nPlayStatus = PLAY_STATUS_FINISHED; + m_sMissionAudio.m_nSampleIndex = NO_SAMPLE; + SampleManager.StopStreamedFile(1); + m_sMissionAudio.m_nMissionAudioCounter = 0; + } + } else { + if (m_nUserPause) + break; + if (nCheckPlayingDelay--) { + if (!SampleManager.IsStreamPlaying(1)) + break; + nCheckPlayingDelay = 0; + } + m_sMissionAudio.field_22 = 1; + } + break; + default: + break; + } + break; + case LOADING_STATUS_FAILED: + if (++nFramesUntilFailedLoad >= 90) { + nFramesForPretendPlaying = 0; + g_bMissionAudioLoadFailed = true; + nFramesUntilFailedLoad = 0; + m_sMissionAudio.m_nLoadingStatus = LOADING_STATUS_LOADED; + } + break; + default: + break; + } +} +#pragma endregion All the mission audio stuff \ No newline at end of file diff --git a/src/audio/AudioManager.cpp b/src/audio/AudioManager.cpp index 63b73a9f..c34ad90a 100644 --- a/src/audio/AudioManager.cpp +++ b/src/audio/AudioManager.cpp @@ -3,341 +3,19 @@ #include "AudioManager.h" #include "audio_enums.h" -#include "Automobile.h" -#include "Boat.h" -#include "Bridge.h" -#include "Camera.h" -#include "Cranes.h" -#include "DMAudio.h" -#include "Entity.h" -#include "Explosion.h" -#include "Fire.h" -#include "Garages.h" -#include "General.h" -#include "HandlingMgr.h" -#include "Heli.h" -#include "ModelIndices.h" +#include "AudioScriptObject.h" #include "MusicManager.h" -#include "Pad.h" -#include "Ped.h" -#include "Physical.h" -#include "Placeable.h" -#include "Plane.h" -#include "PlayerPed.h" -#include "Pools.h" -#include "Projectile.h" -#include "ProjectileInfo.h" -#include "Replay.h" -#include "Stats.h" -#include "SurfaceTable.h" -#include "Train.h" -#include "Transmission.h" -#include "Vehicle.h" -#include "WaterCannon.h" -#include "Weather.h" -#include "ZoneCull.h" +#include "Timer.h" +#include "DMAudio.h" #include "sampman.h" +#include "Camera.h" +#include "World.h" cAudioManager AudioManager; -uint32 gPornNextTime; -uint32 gSawMillNextTime; -uint32 gShopNextTime; -uint32 gAirportNextTime; -uint32 gCinemaNextTime; -uint32 gDocksNextTime; -uint32 gHomeNextTime; -uint32 gCellNextTime; -uint32 gNextCryTime; -uint8 gJumboVolOffsetPercentage; -bool bPlayerJustEnteredCar; -bool g_bMissionAudioLoadFailed; const int channels = ARRAY_SIZE(cAudioManager::m_asActiveSamples); const int policeChannel = channels + 1; const int allChannels = channels + 2; -const int maxVolume = 127; - -const int scriptObjectIntensityS = 30; -const int scriptObjectIntensityL = 80; -const int bridgeIntensity = 400; -const int rocketLauncherIntensity = 90; -const int molotovIntensity = 30; -const int molotovVolume = 50; - -const int rainOnVehicleIntensity = 22; -const int reverseGearIntensity = 30; -const int engineDamageIntensity = 40; - -const bool hornPatternsArray[8][44] = { - {false, false, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, false, false, false, false, false, - false, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, false, false, false, false}, - {false, false, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, - true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, false, false}, - {false, false, true, true, true, true, true, true, true, true, true, true, false, false, false, false, true, true, true, true, true, false, - false, false, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, false}, - {false, false, true, true, true, true, true, false, false, true, true, true, true, true, false, false, false, true, true, true, true, true, - true, true, true, true, true, false, false, false, true, true, true, true, true, true, true, true, true, true, true, true, true, false}, - {false, false, true, true, true, true, true, true, true, true, true, false, false, false, false, false, false, false, false, false, false, false, - false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false}, - {false, false, true, true, true, false, false, false, true, true, true, false, false, false, false, false, false, false, false, false, false, false, - false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false}, - {false, false, true, true, true, true, false, false, false, false, true, true, true, false, false, true, true, true, false, false, true, true, - true, true, true, true, false, false, false, false, false, true, true, true, true, true, true, true, true, true, true, true, false, false}, - {false, false, true, true, true, true, false, false, true, true, true, true, true, false, false, false, true, true, true, true, true, true, - false, false, false, false, true, true, true, true, true, true, true, true, true, true, true, true, true, false, false, false, false, false}, -}; - -const int totalAudioEntitiesSlots = 200; - -const uint8 panTable[64]{0, 3, 8, 12, 16, 19, 22, 24, 26, 28, 30, 31, 33, 34, 36, 37, 39, 40, 41, 42, 44, 45, 46, 47, 48, 49, 49, 50, 51, 52, 53, 53, - 54, 55, 55, 56, 56, 57, 57, 58, 58, 58, 59, 59, 59, 60, 60, 61, 61, 61, 61, 62, 62, 62, 62, 62, 63, 63, 63, 63, 63, 63, 63, 63}; - -// TODO: where is this used? Is this the right file? -enum eVehicleModel { - LANDSTAL, - IDAHO, - STINGER, - LINERUN, - PEREN, - SENTINEL, - RIO, - FIRETRUK, - TRASH, - STRETCH, - MANANA, - INFERNUS, - VOODOO, - PONY, - MULE, - CHEETAH, - AMBULAN, - FBICAR, - MOONBEAM, - ESPERANT, - TAXI, - WASHING, - BOBCAT, - MRWHOOP, - BFINJECT, - HUNTER, - POLICE, - ENFORCER, - SECURICA, - BANSHEE, - PREDATOR, - BUS, - RHINO, - BARRACKS, - CUBAN, - CHOPPER, - ANGEL, - COACH, - CABBIE, - STALLION, - RUMPO, - RCBANDIT, - ROMERO, - PACKER, - SENTXS, - ADMIRAL, - SQUALO, - SEASPAR, - PIZZABOY, - GANGBUR, - AIRTRAIN, - DEADDODO, - SPEEDER, - REEFER, - TROPIC, - FLATBED, - YANKEE, - CADDY, - ZEBRA, - TOPFUN, - SKIMMER, - PCJ600, - FAGGIO, - FREEWAY, - RCBARON, - RCRAIDER, - GLENDALE, - OCEANIC, - SANCHEZ, - SPARROW, - PATRIOT, - LOVEFIST, - COASTG, - DINGHY, - HERMES, - SABRE, - SABRETUR, - PHEONIX, - WALTON, - REGINA, - COMET, - DELUXO, - BURRITO, - SPAND, - MARQUIS, - BAGGAGE, - KAUFMAN, - MAVERICK, - VCNMAV, - RANCHER, - FBIRANCH, - VIRGO, - GREENWOO, - JETMAX, - HOTRING, - SANDKING, - BLISTAC, - POLMAV, - BOXVILLE, - BENSON, - MESA, - RCGOBLIN, - HOTRINA, - HOTRINB, - BLOODRA, - BLOODRB, - VICECHEE, - -// HACK so this compiles -// TODO(MIAMI): check it out -DODO = -1 -}; - -enum PLAY_STATUS : uint8 { PLAY_STATUS_STOPPED = 0, PLAY_STATUS_PLAYING = 1, PLAY_STATUS_FINISHED = 2 }; - -enum LOADING_STATUS : uint8 { LOADING_STATUS_NOT_LOADED = 0, LOADING_STATUS_LOADED = 1 }; - -cPedComments::cPedComments() -{ - for (int i = 0; i < NUM_PED_COMMENTS_SLOTS; i++) - for (int j = 0; j < NUM_PED_COMMENTS_BANKS; j++) { - m_asPedComments[j][i].m_nProcess = -1; - m_nIndexMap[j][i] = NUM_PED_COMMENTS_SLOTS; - } - - for (int i = 0; i < NUM_PED_COMMENTS_BANKS; i++) - m_nCommentsInBank[i] = 0; - m_nActiveBank = 0; -} - -void -cPedComments::Add(tPedComment *com) -{ - uint8 index; - - if (m_nCommentsInBank[m_nActiveBank] >= NUM_PED_COMMENTS_SLOTS) { - index = m_nIndexMap[m_nActiveBank][NUM_PED_COMMENTS_SLOTS - 1]; - if (m_asPedComments[m_nActiveBank][index].m_bVolume > com->m_bVolume) - return; - } else { - index = m_nCommentsInBank[m_nActiveBank]++; - } - - m_asPedComments[m_nActiveBank][index].m_nSampleIndex = com->m_nSampleIndex; - m_asPedComments[m_nActiveBank][index].m_nEntityIndex = com->m_nEntityIndex; - m_asPedComments[m_nActiveBank][index].m_vecPos = com->m_vecPos; - m_asPedComments[m_nActiveBank][index].m_fDistance = com->m_fDistance; - m_asPedComments[m_nActiveBank][index].m_bVolume = com->m_bVolume; - - uint32 i = 0; - if (index != 0) { - for (i = 0; i < index; i++) { - if (m_asPedComments[m_nActiveBank][m_nIndexMap[m_nActiveBank][i]].m_bVolume < m_asPedComments[m_nActiveBank][index].m_bVolume) { - break; - } - } - - if (i < index) - memmove(&m_nIndexMap[m_nActiveBank][i + 1], &m_nIndexMap[m_nActiveBank][i], NUM_PED_COMMENTS_SLOTS - 1 - i); - } - - m_nIndexMap[m_nActiveBank][i] = index; -} - -void -cPedComments::Process() -{ - int sampleIndex; - uint8 actualUsedBank; - tPedComment *comment; - - static const int defaultIntensity = 50; - static const int policeHeliIntensity = 400; - - if (!AudioManager.m_nUserPause) { - if (m_nCommentsInBank[m_nActiveBank]) { - sampleIndex = m_asPedComments[m_nActiveBank][m_nIndexMap[m_nActiveBank][0]].m_nSampleIndex; - if (!SampleManager.IsPedCommentLoaded(sampleIndex)) - SampleManager.LoadPedComment(sampleIndex); - - AudioManager.m_sQueueSample.m_nEntityIndex = m_asPedComments[m_nActiveBank][m_nIndexMap[m_nActiveBank][0]].m_nEntityIndex; - AudioManager.m_sQueueSample.m_nCounter = 0; - AudioManager.m_sQueueSample.m_nSampleIndex = sampleIndex; - AudioManager.m_sQueueSample.m_nBankIndex = SAMPLEBANK_PED; - AudioManager.m_sQueueSample.m_nReleasingVolumeModificator = 3; - AudioManager.m_sQueueSample.m_nVolume = m_asPedComments[m_nActiveBank][m_nIndexMap[m_nActiveBank][0]].m_bVolume; - AudioManager.m_sQueueSample.m_fDistance = m_asPedComments[m_nActiveBank][m_nIndexMap[m_nActiveBank][0]].m_fDistance; - AudioManager.m_sQueueSample.m_nLoopCount = 1; - AudioManager.m_sQueueSample.m_nLoopStart = 0; - AudioManager.m_sQueueSample.m_nLoopEnd = -1; - AudioManager.m_sQueueSample.m_nEmittingVolume = maxVolume; - AudioManager.m_sQueueSample.m_fSpeedMultiplier = 3.0f; - switch (sampleIndex) { - case SFX_POLICE_HELI_1: - case SFX_POLICE_HELI_2: - case SFX_POLICE_HELI_3: - AudioManager.m_sQueueSample.m_fSoundIntensity = policeHeliIntensity; - break; - default: - AudioManager.m_sQueueSample.m_fSoundIntensity = defaultIntensity; - break; - } - AudioManager.m_sQueueSample.m_bReleasingSoundFlag = true; - AudioManager.m_sQueueSample.m_vecPos = m_asPedComments[m_nActiveBank][m_nIndexMap[m_nActiveBank][0]].m_vecPos; - - if (sampleIndex >= SFX_AMMU_D && sampleIndex <= SFX_AMMU_F) { - AudioManager.m_sQueueSample.m_bReverbFlag = false; - AudioManager.m_sQueueSample.m_bRequireReflection = false; - } else { - AudioManager.m_sQueueSample.m_bReverbFlag = true; - AudioManager.m_sQueueSample.m_bRequireReflection = true; - } - - AudioManager.m_sQueueSample.m_bIs2D = false; - AudioManager.m_sQueueSample.m_nFrequency = - SampleManager.GetSampleBaseFrequency(AudioManager.m_sQueueSample.m_nSampleIndex) + AudioManager.RandomDisplacement(750); - if (CTimer::GetIsSlowMotionActive()) - AudioManager.m_sQueueSample.m_nFrequency /= 2; - m_asPedComments[m_nActiveBank][m_nIndexMap[m_nActiveBank][0]].m_nProcess = -1; - AudioManager.AddSampleToRequestedQueue(); - } - - // Switch bank - if (m_nActiveBank) { - actualUsedBank = SAMPLEBANK_PED; - m_nActiveBank = SAMPLEBANK_MAIN; - } else { - actualUsedBank = SAMPLEBANK_MAIN; - m_nActiveBank = SAMPLEBANK_PED; - } - comment = m_asPedComments[actualUsedBank]; - for (uint32 i = 0; i < m_nCommentsInBank[actualUsedBank]; i++) { - if (m_asPedComments[actualUsedBank][m_nIndexMap[actualUsedBank][i]].m_nProcess > 0) { - --m_asPedComments[actualUsedBank][m_nIndexMap[actualUsedBank][i]].m_nProcess; - Add(&comment[m_nIndexMap[actualUsedBank][i]]); - } - } - - for (uint32 i = 0; i < NUM_PED_COMMENTS_SLOTS; i++) { - m_nIndexMap[actualUsedBank][i] = NUM_PED_COMMENTS_SLOTS; - } - m_nCommentsInBank[actualUsedBank] = 0; - } -} cAudioManager::cAudioManager() { @@ -353,7 +31,7 @@ cAudioManager::cAudioManager() ClearActiveSamples(); GenerateIntegerRandomNumberTable(); field_4 = 0; - m_bDynamicAcousticModelingStatus = 1; + m_bDynamicAcousticModelingStatus = true; for (int i = 0; i < NUM_AUDIOENTITIES; i++) { m_asAudioEntities[i].m_bIsUsed = false; @@ -361,8 +39,8 @@ cAudioManager::cAudioManager() } m_nAudioEntitiesTotal = 0; m_FrameCounter = 0; - m_bFifthFrameFlag = 0; - m_bTimerJustReset = 0; + m_bFifthFrameFlag = false; + m_bTimerJustReset = false; m_nTimer = 0; } @@ -372,6 +50,536 @@ cAudioManager::~cAudioManager() Terminate(); } +void +cAudioManager::Initialise() +{ + if (!m_bIsInitialised) { + PreInitialiseGameSpecificSetup(); + m_bIsInitialised = SampleManager.Initialise(); + if (m_bIsInitialised) { + m_nActiveSamples = SampleManager.GetMaximumSupportedChannels(); + if (m_nActiveSamples <= 1) { + Terminate(); + } else { + --m_nActiveSamples; + PostInitialiseGameSpecificSetup(); + InitialisePoliceRadioZones(); + InitialisePoliceRadio(); + MusicManager.Initialise(); + } + } + } +} + +void +cAudioManager::Terminate() +{ + if (m_bIsInitialised) { + MusicManager.Terminate(); + + for (uint32 i = 0; i < NUM_AUDIOENTITIES; i++) { + m_asAudioEntities[i].m_bIsUsed = false; + m_anAudioEntityIndices[i] = ARRAY_SIZE(m_anAudioEntityIndices); + } + + m_nAudioEntitiesTotal = 0; + m_sAudioScriptObjectManager.m_nScriptObjectEntityTotal = 0; + PreTerminateGameSpecificShutdown(); + + for (uint32 i = 0; i < MAX_SAMPLEBANKS; i++) { + if (SampleManager.IsSampleBankLoaded(i)) + SampleManager.UnloadSampleBank(i); + } + + SampleManager.Terminate(); + + m_bIsInitialised = false; + PostTerminateGameSpecificShutdown(); + } +} + +void +cAudioManager::Service() +{ + GenerateIntegerRandomNumberTable(); + if (m_bTimerJustReset) { + ResetAudioLogicTimers(m_nTimer); + MusicManager.ResetTimers(m_nTimer); + m_bTimerJustReset = false; + } + if (m_bIsInitialised) { + m_nPreviousUserPause = m_nUserPause; + m_nUserPause = CTimer::GetIsUserPaused(); + UpdateReflections(); + ServiceSoundEffects(); + MusicManager.Service(); + } +} + +int32 +cAudioManager::CreateEntity(eAudioType type, void *entity) +{ + if (!m_bIsInitialised) + return AEHANDLE_ERROR_NOAUDIOSYS; + if (!entity) + return AEHANDLE_ERROR_NOENTITY; + if (type >= TOTAL_AUDIO_TYPES) + return AEHANDLE_ERROR_BADAUDIOTYPE; + for (uint32 i = 0; i < ARRAY_SIZE(m_asAudioEntities); i++) { + if (!m_asAudioEntities[i].m_bIsUsed) { + m_asAudioEntities[i].m_bIsUsed = true; + m_asAudioEntities[i].m_nStatus = 0; + m_asAudioEntities[i].m_nType = type; + m_asAudioEntities[i].m_pEntity = entity; + m_asAudioEntities[i].m_awAudioEvent[0] = SOUND_NO_SOUND; + m_asAudioEntities[i].m_awAudioEvent[1] = SOUND_NO_SOUND; + m_asAudioEntities[i].m_awAudioEvent[2] = SOUND_NO_SOUND; + m_asAudioEntities[i].m_awAudioEvent[3] = SOUND_NO_SOUND; + m_asAudioEntities[i].m_AudioEvents = 0; + m_anAudioEntityIndices[m_nAudioEntitiesTotal++] = i; + return i; + } + } + return AEHANDLE_ERROR_NOFREESLOT; +} + +void +cAudioManager::DestroyEntity(int32 id) +{ + if (m_bIsInitialised && id >= 0 && id < NUM_AUDIOENTITIES && m_asAudioEntities[id].m_bIsUsed) { + m_asAudioEntities[id].m_bIsUsed = false; + for (int32 i = 0; i < m_nAudioEntitiesTotal; ++i) { + if (id == m_anAudioEntityIndices[i]) { + if (i < NUM_AUDIOENTITIES - 1) + memmove(&m_anAudioEntityIndices[i], &m_anAudioEntityIndices[i + 1], NUM_AUDIOENTITY_EVENTS * (m_nAudioEntitiesTotal - (i + 1))); + m_anAudioEntityIndices[--m_nAudioEntitiesTotal] = NUM_AUDIOENTITIES; + return; + } + } + } +} + +void +cAudioManager::SetEntityStatus(int32 id, uint8 status) +{ + if (m_bIsInitialised && id >= 0 && id < NUM_AUDIOENTITIES && m_asAudioEntities[id].m_bIsUsed) + m_asAudioEntities[id].m_nStatus = status; +} + +void +cAudioManager::PlayOneShot(int32 index, int16 sound, float vol) +{ + static const uint8 OneShotPriority[] = {3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 5, 5, 5, 3, 5, 2, 2, 1, 1, 3, 1, 3, 3, 1, 1, 1, 4, 4, 3, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 6, 1, 1, 3, 2, 2, 2, 2, 0, 0, 6, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 3, 1, 1, 1, 9, + 2, 2, 0, 0, 0, 0, 3, 3, 5, 1, 1, 1, 1, 3, 4, 7, 6, 6, 6, 6, 1, 3, 4, 3, 4, 2, 1, 3, 5, 4, 6, 6, 1, 3, + 1, 1, 1, 0, 0, 0, 0, 0, 0, 3, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + + if (m_bIsInitialised) { + if (index >= 0 && index < NUM_AUDIOENTITIES) { + tAudioEntity &entity = m_asAudioEntities[index]; + if (entity.m_bIsUsed) { + if (sound < SOUND_TOTAL_SOUNDS) { + if (entity.m_nType == AUDIOTYPE_SCRIPTOBJECT) { + if (m_sAudioScriptObjectManager.m_nScriptObjectEntityTotal < ARRAY_SIZE(m_sAudioScriptObjectManager.m_anScriptObjectEntityIndices)) { + entity.m_awAudioEvent[0] = sound; + entity.m_AudioEvents = 1; + m_sAudioScriptObjectManager.m_anScriptObjectEntityIndices[m_sAudioScriptObjectManager.m_nScriptObjectEntityTotal++] = index; + } + } else { + int32 i = 0; + while (true) { + if (i >= entity.m_AudioEvents) { + if (entity.m_AudioEvents < ARRAY_SIZE(entity.m_awAudioEvent)) { + entity.m_awAudioEvent[i] = sound; + entity.m_afVolume[i] = vol; + ++entity.m_AudioEvents; + } + return; + } + if (OneShotPriority[entity.m_awAudioEvent[i]] > OneShotPriority[sound]) + break; + ++i; + } + if (i < NUM_AUDIOENTITY_EVENTS - 1) { + memmove(&entity.m_awAudioEvent[i + 1], &entity.m_awAudioEvent[i], (NUM_AUDIOENTITY_EVENTS - 1 - i) * NUM_AUDIOENTITY_EVENTS / 2); + memmove(&entity.m_afVolume[i + 1], &entity.m_afVolume[i], (NUM_AUDIOENTITY_EVENTS - 1 - i) * NUM_AUDIOENTITY_EVENTS); + } + entity.m_awAudioEvent[i] = sound; + entity.m_afVolume[i] = vol; + if (entity.m_AudioEvents < ARRAY_SIZE(entity.m_awAudioEvent)) + ++entity.m_AudioEvents; + } + } + } + } + } +} + +void +cAudioManager::SetEffectsMasterVolume(uint8 volume) const +{ + SampleManager.SetEffectsMasterVolume(volume); +} + +void +cAudioManager::SetMusicMasterVolume(uint8 volume) const +{ + SampleManager.SetMusicMasterVolume(volume); +} + +void +cAudioManager::SetEffectsFadeVol(uint8 volume) const +{ + SampleManager.SetEffectsFadeVolume(volume); +} + +void +cAudioManager::SetMusicFadeVol(uint8 volume) const +{ + SampleManager.SetMusicFadeVolume(volume); +} + +void +cAudioManager::ResetTimers(uint32 time) +{ + if (m_bIsInitialised) { + m_bTimerJustReset = true; + m_nTimer = time; + ClearRequestedQueue(); + if (m_nActiveSampleQueue) { + m_nActiveSampleQueue = 0; + ClearRequestedQueue(); + m_nActiveSampleQueue = 1; + } else { + m_nActiveSampleQueue = 1; + ClearRequestedQueue(); + m_nActiveSampleQueue = 0; + } + ClearActiveSamples(); + ClearMissionAudio(); + SampleManager.StopChannel(policeChannel); + SampleManager.SetEffectsFadeVolume(0); + SampleManager.SetMusicFadeVolume(0); + MusicManager.ResetMusicAfterReload(); +#ifdef AUDIO_OAL + SampleManager.Service(); +#endif + } +} + +void +cAudioManager::DestroyAllGameCreatedEntities() +{ + cAudioScriptObject *entity; + + if (m_bIsInitialised) { + for (uint32 i = 0; i < ARRAY_SIZE(m_asAudioEntities); i++) { + if (m_asAudioEntities[i].m_bIsUsed) { + switch (m_asAudioEntities[i].m_nType) { + case AUDIOTYPE_PHYSICAL: + case AUDIOTYPE_EXPLOSION: + case AUDIOTYPE_WEATHER: + case AUDIOTYPE_CRANE: + case AUDIOTYPE_GARAGE: + case AUDIOTYPE_FIREHYDRANT: + DestroyEntity(i); + break; + case AUDIOTYPE_SCRIPTOBJECT: + entity = (cAudioScriptObject *)m_asAudioEntities[i].m_pEntity; + if (entity) { + delete entity; + m_asAudioEntities[i].m_pEntity = nil; + } + DestroyEntity(i); + break; + default: + break; + } + } + } + m_sAudioScriptObjectManager.m_nScriptObjectEntityTotal = 0; + } +} + +uint8 +cAudioManager::GetNum3DProvidersAvailable() const +{ + if (m_bIsInitialised) + return SampleManager.GetNum3DProvidersAvailable(); + return 0; +} + +char * +cAudioManager::Get3DProviderName(uint8 id) const +{ + if (!m_bIsInitialised) + return nil; + if (id >= SampleManager.GetNum3DProvidersAvailable()) + return nil; + return SampleManager.Get3DProviderName(id); +} + +int8 +cAudioManager::GetCurrent3DProviderIndex() const +{ + if (m_bIsInitialised) + return SampleManager.GetCurrent3DProviderIndex(); + + return -1; +} + +int8 +cAudioManager::SetCurrent3DProvider(uint8 which) +{ + if (!m_bIsInitialised) + return -1; + for (uint8 i = 0; i < m_nActiveSamples + 1; ++i) + SampleManager.StopChannel(i); + ClearRequestedQueue(); + if (m_nActiveSampleQueue == 0) + m_nActiveSampleQueue = 1; + else + m_nActiveSampleQueue = 0; + ClearRequestedQueue(); + ClearActiveSamples(); + int8 current = SampleManager.SetCurrent3DProvider(which); + if (current > 0) { + m_nActiveSamples = SampleManager.GetMaximumSupportedChannels(); + if (m_nActiveSamples > 1) + --m_nActiveSamples; + } + return current; +} + +void +cAudioManager::SetSpeakerConfig(int32 conf) const +{ + SampleManager.SetSpeakerConfig(conf); +} + +bool +cAudioManager::IsMP3RadioChannelAvailable() const +{ + if (m_bIsInitialised) + return SampleManager.IsMP3RadioChannelAvailable(); + + return false; +} + +void +cAudioManager::ReleaseDigitalHandle() const +{ + if (m_bIsInitialised) { + SampleManager.ReleaseDigitalHandle(); + } +} + +void +cAudioManager::ReacquireDigitalHandle() const +{ + if (m_bIsInitialised) { + SampleManager.ReacquireDigitalHandle(); + } +} + +void +cAudioManager::SetDynamicAcousticModelingStatus(bool status) +{ + m_bDynamicAcousticModelingStatus = status; +} + +bool +cAudioManager::CheckForAnAudioFileOnCD() const +{ + return SampleManager.CheckForAnAudioFileOnCD(); +} + +uint8 +cAudioManager::GetCDAudioDriveLetter() const +{ + if (m_bIsInitialised) + return SampleManager.GetCDAudioDriveLetter(); + + return 0; +} + +bool +cAudioManager::IsAudioInitialised() const +{ + return m_bIsInitialised; +} + +void +cAudioManager::ServiceSoundEffects() +{ + m_bFifthFrameFlag = (m_FrameCounter++ % 5) == 0; + if (m_nUserPause && !m_nPreviousUserPause) { + for (int32 i = 0; i < allChannels; i++) + SampleManager.StopChannel(i); + + ClearRequestedQueue(); + if (m_nActiveSampleQueue) { + m_nActiveSampleQueue = 0; + ClearRequestedQueue(); + m_nActiveSampleQueue = 1; + } else { + m_nActiveSampleQueue = 1; + ClearRequestedQueue(); + m_nActiveSampleQueue = 0; + } + ClearActiveSamples(); + } + m_nActiveSampleQueue = m_nActiveSampleQueue != 1; + ProcessReverb(); + ProcessSpecial(); + ClearRequestedQueue(); + InterrogateAudioEntities(); + m_sPedComments.Process(); + ServicePoliceRadio(); + ServiceCollisions(); + AddReleasingSounds(); + ProcessMissionAudio(); +#ifdef GTA_PC + AdjustSamplesVolume(); +#endif + ProcessActiveQueues(); +#ifdef AUDIO_OAL + SampleManager.Service(); +#endif + for (int32 i = 0; i < m_sAudioScriptObjectManager.m_nScriptObjectEntityTotal; ++i) { + cAudioScriptObject *object = (cAudioScriptObject *)m_asAudioEntities[m_sAudioScriptObjectManager.m_anScriptObjectEntityIndices[i]].m_pEntity; + delete object; + m_asAudioEntities[m_sAudioScriptObjectManager.m_anScriptObjectEntityIndices[i]].m_pEntity = nil; + DestroyEntity(m_sAudioScriptObjectManager.m_anScriptObjectEntityIndices[i]); + } + m_sAudioScriptObjectManager.m_nScriptObjectEntityTotal = 0; +} + +uint8 +cAudioManager::ComputeVolume(uint8 emittingVolume, float soundIntensity, float distance) const +{ + float newSoundIntensity; + if (soundIntensity <= 0.0f) + return 0; + newSoundIntensity = soundIntensity / 5.0f; + if (newSoundIntensity <= distance) + emittingVolume = sq((soundIntensity - newSoundIntensity - (distance - newSoundIntensity)) / (soundIntensity - newSoundIntensity)) * emittingVolume; + return emittingVolume; +} + +void +cAudioManager::TranslateEntity(Const CVector *in, CVector *out) const +{ + *out = MultiplyInverse(TheCamera.GetMatrix(), *in); +} + +int32 +cAudioManager::ComputePan(float dist, CVector *vec) +{ + const uint8 PanTable[64] = {0, 3, 8, 12, 16, 19, 22, 24, 26, 28, 30, 31, 33, 34, 36, 37, 39, 40, 41, 42, 44, 45, 46, 47, 48, 49, 49, 50, 51, 52, 53, 53, + 54, 55, 55, 56, 56, 57, 57, 58, 58, 58, 59, 59, 59, 60, 60, 61, 61, 61, 61, 62, 62, 62, 62, 62, 63, 63, 63, 63, 63, 63, 63, 63}; + + int32 index = Min(63, Abs(vec->x / (dist / 64.f))); + + if (vec->x > 0.f) + return Max(20, 63 - PanTable[index]); + return Min(107, PanTable[index] + 63); +} + +int32 +cAudioManager::ComputeDopplerEffectedFrequency(uint32 oldFreq, float position1, float position2, float speedMultiplier) const +{ + uint32 newFreq = oldFreq; + if (!TheCamera.Get_Just_Switched_Status() && speedMultiplier != 0.0f) { + float dist = position2 - position1; + if (dist != 0.0f) { + float speedOfSource = (dist / m_nTimeSpent) * speedMultiplier; + if (m_fSpeedOfSound > Abs(speedOfSource)) { + if (speedOfSource < 0.0f) { + speedOfSource = Max(speedOfSource, -1.5f); + } else { + speedOfSource = Min(speedOfSource, 1.5f); + } + newFreq = (oldFreq * m_fSpeedOfSound) / (speedOfSource + m_fSpeedOfSound); + } + } + } + return newFreq; +} + +int32 +cAudioManager::RandomDisplacement(uint32 seed) const +{ + int32 value; + + static bool bPos = true; + static uint32 Adjustment = 0; + + if (!seed) + return 0; + + value = m_anRandomTable[(Adjustment + seed) % 5] % seed; + Adjustment += value; + + if (value % 2) { + bPos = !bPos; + } + if (!bPos) + value = -value; + return value; +} + +void +cAudioManager::InterrogateAudioEntities() +{ + for (int32 i = 0; i < m_nAudioEntitiesTotal; i++) { + ProcessEntity(m_anAudioEntityIndices[i]); + m_asAudioEntities[m_anAudioEntityIndices[i]].m_AudioEvents = 0; + } +} + +void +cAudioManager::AddSampleToRequestedQueue() +{ + int32 calculatedVolume; + uint8 sampleIndex; + bool bReflections; + + if (m_sQueueSample.m_nSampleIndex < TOTAL_AUDIO_SAMPLES) { + calculatedVolume = m_sQueueSample.m_nReleasingVolumeModificator * (MAX_VOLUME - m_sQueueSample.m_nVolume); + sampleIndex = m_SampleRequestQueuesStatus[m_nActiveSampleQueue]; + if (sampleIndex >= m_nActiveSamples) { + sampleIndex = m_abSampleQueueIndexTable[m_nActiveSampleQueue][m_nActiveSamples - 1]; + if (m_asSamples[m_nActiveSampleQueue][sampleIndex].m_nCalculatedVolume <= calculatedVolume) + return; + } else { + ++m_SampleRequestQueuesStatus[m_nActiveSampleQueue]; + } + m_sQueueSample.m_nCalculatedVolume = calculatedVolume; + m_sQueueSample.m_bLoopEnded = false; + if (m_sQueueSample.m_bIs2D) { + m_sQueueSample.m_bRequireReflection = false; + m_sQueueSample.m_nLoopsRemaining = 0; + } + if (m_bDynamicAcousticModelingStatus && m_sQueueSample.m_nLoopCount) { + bReflections = m_sQueueSample.m_bRequireReflection; + } else { + bReflections = false; + m_sQueueSample.m_nLoopsRemaining = 0; + } + m_sQueueSample.m_bRequireReflection = false; + + if (!m_bDynamicAcousticModelingStatus) + m_sQueueSample.m_bReverbFlag = false; + + m_asSamples[m_nActiveSampleQueue][sampleIndex] = m_sQueueSample; + + AddDetailsToRequestedOrderList(sampleIndex); + if (bReflections) + AddReflectionsToRequestedQueue(); + } +} void cAudioManager::AddDetailsToRequestedOrderList(uint8 sample) { @@ -389,35 +597,6 @@ cAudioManager::AddDetailsToRequestedOrderList(uint8 sample) m_abSampleQueueIndexTable[m_nActiveSampleQueue][i] = sample; } -void -cAudioManager::AddPlayerCarSample(uint8 emittingVolume, int32 freq, uint32 sample, uint8 unk1, uint8 counter, bool notLooping) -{ - m_sQueueSample.m_nVolume = ComputeVolume(emittingVolume, 50.f, m_sQueueSample.m_fDistance); - if (m_sQueueSample.m_nVolume) { - m_sQueueSample.m_nCounter = counter; - m_sQueueSample.m_nSampleIndex = sample; - m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; - m_sQueueSample.m_bIs2D = false; - m_sQueueSample.m_nReleasingVolumeModificator = 0; - m_sQueueSample.m_nFrequency = freq; - if (notLooping) { - m_sQueueSample.m_nLoopCount = 0; - m_sQueueSample.m_nReleasingVolumeDivider = 8; - } else { - m_sQueueSample.m_nLoopCount = 1; - } - m_sQueueSample.m_nEmittingVolume = emittingVolume; - m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex); - m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex); - m_sQueueSample.m_fSpeedMultiplier = 6.0f; - m_sQueueSample.m_fSoundIntensity = 50.0f; - m_sQueueSample.m_bReleasingSoundFlag = false; - m_sQueueSample.m_bReverbFlag = true; - m_sQueueSample.m_bRequireReflection = false; - AddSampleToRequestedQueue(); - } -} - void cAudioManager::AddReflectionsToRequestedQueue() { @@ -451,6 +630,51 @@ cAudioManager::AddReflectionsToRequestedQueue() } } +void +cAudioManager::UpdateReflections() +{ + const CVector &camPos = TheCamera.GetPosition(); + CColPoint colpoint; + CEntity *ent; + + if (m_FrameCounter % 8 == 0) { + m_avecReflectionsPos[0] = camPos; + m_avecReflectionsPos[0].y += 50.f; + if (CWorld::ProcessLineOfSight(camPos, m_avecReflectionsPos[0], colpoint, ent, true, false, false, true, false, true, true)) + m_afReflectionsDistances[0] = Distance(camPos, colpoint.point); + else + m_afReflectionsDistances[0] = 50.0f; + } else if ((m_FrameCounter + 1) % 8 == 0) { + m_avecReflectionsPos[1] = camPos; + m_avecReflectionsPos[1].y -= 50.0f; + if (CWorld::ProcessLineOfSight(camPos, m_avecReflectionsPos[1], colpoint, ent, true, false, false, true, false, true, true)) + m_afReflectionsDistances[1] = Distance(camPos, colpoint.point); + else + m_afReflectionsDistances[1] = 50.0f; + } else if ((m_FrameCounter + 2) % 8 == 0) { + m_avecReflectionsPos[2] = camPos; + m_avecReflectionsPos[2].x -= 50.0f; + if (CWorld::ProcessLineOfSight(camPos, m_avecReflectionsPos[2], colpoint, ent, true, false, false, true, false, true, true)) + m_afReflectionsDistances[2] = Distance(camPos, colpoint.point); + else + m_afReflectionsDistances[2] = 50.0f; + } else if ((m_FrameCounter + 3) % 8 == 0) { + m_avecReflectionsPos[3] = camPos; + m_avecReflectionsPos[3].x += 50.0f; + if (CWorld::ProcessLineOfSight(camPos, m_avecReflectionsPos[3], colpoint, ent, true, false, false, true, false, true, true)) + m_afReflectionsDistances[3] = Distance(camPos, colpoint.point); + else + m_afReflectionsDistances[3] = 50.0f; + } else if ((m_FrameCounter + 4) % 8 == 0) { + m_avecReflectionsPos[4] = camPos; + m_avecReflectionsPos[4].z += 50.0f; + if (CWorld::ProcessVerticalLine(camPos, m_avecReflectionsPos[4].z, colpoint, ent, true, false, false, false, true, false, nil)) + m_afReflectionsDistances[4] = colpoint.point.z - camPos.z; + else + m_afReflectionsDistances[4] = 50.0f; + } +} + void cAudioManager::AddReleasingSounds() { @@ -500,3072 +724,6 @@ cAudioManager::AddReleasingSounds() } } -void -cAudioManager::AddSampleToRequestedQueue() -{ - int32 calculatedVolume; - uint8 sampleIndex; - bool bReflections; - - if (m_sQueueSample.m_nSampleIndex < TOTAL_AUDIO_SAMPLES) { - calculatedVolume = m_sQueueSample.m_nReleasingVolumeModificator * (maxVolume - m_sQueueSample.m_nVolume); - sampleIndex = m_SampleRequestQueuesStatus[m_nActiveSampleQueue]; - if (sampleIndex >= m_nActiveSamples) { - sampleIndex = m_abSampleQueueIndexTable[m_nActiveSampleQueue][m_nActiveSamples - 1]; - if (m_asSamples[m_nActiveSampleQueue][sampleIndex].m_nCalculatedVolume <= calculatedVolume) - return; - } else { - ++m_SampleRequestQueuesStatus[m_nActiveSampleQueue]; - } - m_sQueueSample.m_nCalculatedVolume = calculatedVolume; - m_sQueueSample.m_bLoopEnded = false; - if (m_sQueueSample.m_bIs2D) { - m_sQueueSample.m_bRequireReflection = false; - m_sQueueSample.m_nLoopsRemaining = 0; - } - if (m_bDynamicAcousticModelingStatus && m_sQueueSample.m_nLoopCount) { - bReflections = m_sQueueSample.m_bRequireReflection; - } else { - bReflections = false; - m_sQueueSample.m_nLoopsRemaining = 0; - } - m_sQueueSample.m_bRequireReflection = false; - - if (!m_bDynamicAcousticModelingStatus) - m_sQueueSample.m_bReverbFlag = false; - - m_asSamples[m_nActiveSampleQueue][sampleIndex] = m_sQueueSample; - - AddDetailsToRequestedOrderList(sampleIndex); - if (bReflections) - AddReflectionsToRequestedQueue(); - } -} - -void -cAudioManager::CalculateDistance(bool &distCalculated, float dist) -{ - if (!distCalculated) { - m_sQueueSample.m_fDistance = Sqrt(dist); - distCalculated = true; - } -} - -bool -cAudioManager::CheckForAnAudioFileOnCD() const -{ - return SampleManager.CheckForAnAudioFileOnCD(); -} - -void -cAudioManager::ClearActiveSamples() -{ - for (int32 i = 0; i < m_nActiveSamples; i++) { - m_asActiveSamples[i].m_nEntityIndex = AEHANDLE_NONE; - m_asActiveSamples[i].m_nCounter = 0; - m_asActiveSamples[i].m_nSampleIndex = NO_SAMPLE; - m_asActiveSamples[i].m_nBankIndex = SAMPLEBANK_INVALID; - m_asActiveSamples[i].m_bIs2D = false; - m_asActiveSamples[i].m_nReleasingVolumeModificator = 5; - m_asActiveSamples[i].m_nFrequency = 0; - m_asActiveSamples[i].m_nVolume = 0; - m_asActiveSamples[i].m_nEmittingVolume = 0; - m_asActiveSamples[i].m_fDistance = 0.0f; - m_asActiveSamples[i].m_bIsProcessed = false; - m_asActiveSamples[i].m_bLoopEnded = false; - m_asActiveSamples[i].m_nLoopCount = 1; - m_asActiveSamples[i].m_nLoopStart = 0; - m_asActiveSamples[i].m_nLoopEnd = -1; - m_asActiveSamples[i].m_fSpeedMultiplier = 0.0f; - m_asActiveSamples[i].m_fSoundIntensity = 200.0f; - m_asActiveSamples[i].m_nOffset = 63; - m_asActiveSamples[i].m_bReleasingSoundFlag = false; - m_asActiveSamples[i].m_nCalculatedVolume = 0; - m_asActiveSamples[i].m_nReleasingVolumeDivider = 0; - m_asActiveSamples[i].m_nVolumeChange = -1; - m_asActiveSamples[i].m_vecPos = {0.0f, 0.0f, 0.0f}; - m_asActiveSamples[i].m_bReverbFlag = false; - m_asActiveSamples[i].m_nLoopsRemaining = 0; - m_asActiveSamples[i].m_bRequireReflection = false; - } -} - -void -cAudioManager::ClearMissionAudio() -{ - if (m_bIsInitialised) { - m_sMissionAudio.m_nSampleIndex = NO_SAMPLE; - m_sMissionAudio.m_nLoadingStatus = LOADING_STATUS_NOT_LOADED; - m_sMissionAudio.m_nPlayStatus = PLAY_STATUS_STOPPED; - m_sMissionAudio.field_22 = 0; - m_sMissionAudio.m_bIsPlayed = false; - m_sMissionAudio.m_bPredefinedProperties = 1; - m_sMissionAudio.m_nMissionAudioCounter = 0; - } -} - -void -cAudioManager::ClearRequestedQueue() -{ - for (int32 i = 0; i < m_nActiveSamples; i++) { - m_abSampleQueueIndexTable[m_nActiveSampleQueue][i] = m_nActiveSamples; - } - m_SampleRequestQueuesStatus[m_nActiveSampleQueue] = 0; -} - -int32 -cAudioManager::ComputeDopplerEffectedFrequency(uint32 oldFreq, float position1, float position2, float speedMultiplier) const -{ - uint32 newFreq = oldFreq; - if (!TheCamera.Get_Just_Switched_Status() && speedMultiplier != 0.0f) { - float dist = position2 - position1; - if (dist != 0.0f) { - float speedOfSource = (dist / m_nTimeSpent) * speedMultiplier; - if (m_fSpeedOfSound > Abs(speedOfSource)) { - if (speedOfSource < 0.0f) { - speedOfSource = Max(speedOfSource, -1.5f); - } else { - speedOfSource = Min(speedOfSource, 1.5f); - } - newFreq = (oldFreq * m_fSpeedOfSound) / (speedOfSource + m_fSpeedOfSound); - } - } - } - return newFreq; -} - -int32 -cAudioManager::ComputePan(float dist, CVector *vec) -{ - int32 index = Min(63, Abs(vec->x / (dist / 64.f))); - - if (vec->x > 0.f) - return Max(20, 63 - panTable[index]); - return Min(107, panTable[index] + 63); -} - -uint8 -cAudioManager::ComputeVolume(uint8 emittingVolume, float soundIntensity, float distance) const -{ - float newSoundIntensity; - if (soundIntensity <= 0.0f) - return 0; - newSoundIntensity = soundIntensity / 5.0f; - if (newSoundIntensity <= distance) - emittingVolume = sq((soundIntensity - newSoundIntensity - (distance - newSoundIntensity)) / (soundIntensity - newSoundIntensity)) * emittingVolume; - return emittingVolume; -} - -int32 -cAudioManager::CreateEntity(int32 type, void *entity) -{ - if (!m_bIsInitialised) - return AEHANDLE_ERROR_NOAUDIOSYS; - if (!entity) - return AEHANDLE_ERROR_NOENTITY; - if (type >= TOTAL_AUDIO_TYPES) - return AEHANDLE_ERROR_BADAUDIOTYPE; - for (uint32 i = 0; i < ARRAY_SIZE(m_asAudioEntities); i++) { - if (!m_asAudioEntities[i].m_bIsUsed) { - m_asAudioEntities[i].m_bIsUsed = true; - m_asAudioEntities[i].m_nStatus = 0; - m_asAudioEntities[i].m_nType = (eAudioType)type; - m_asAudioEntities[i].m_pEntity = entity; - m_asAudioEntities[i].m_awAudioEvent[0] = SOUND_TOTAL_PED_SOUNDS; - m_asAudioEntities[i].m_awAudioEvent[1] = SOUND_TOTAL_PED_SOUNDS; - m_asAudioEntities[i].m_awAudioEvent[2] = SOUND_TOTAL_PED_SOUNDS; - m_asAudioEntities[i].m_awAudioEvent[3] = SOUND_TOTAL_PED_SOUNDS; - m_asAudioEntities[i].m_AudioEvents = 0; - m_anAudioEntityIndices[m_nAudioEntitiesTotal++] = i; - return i; - } - } - return AEHANDLE_ERROR_NOFREESLOT; -} - -void -cAudioManager::DestroyAllGameCreatedEntities() -{ - cAudioScriptObject *entity; - - if (m_bIsInitialised) { - for (uint32 i = 0; i < ARRAY_SIZE(m_asAudioEntities); i++) { - if (m_asAudioEntities[i].m_bIsUsed) { - switch (m_asAudioEntities[i].m_nType) { - case AUDIOTYPE_PHYSICAL: - case AUDIOTYPE_EXPLOSION: - case AUDIOTYPE_WEATHER: - case AUDIOTYPE_CRANE: - case AUDIOTYPE_GARAGE: - case AUDIOTYPE_FIREHYDRANT: - DestroyEntity(i); - break; - case AUDIOTYPE_SCRIPTOBJECT: - entity = (cAudioScriptObject *)m_asAudioEntities[i].m_pEntity; - if (entity) { - delete entity; - m_asAudioEntities[i].m_pEntity = nil; - } - DestroyEntity(i); - break; - default: - break; - } - } - } - m_sAudioScriptObjectManager.m_nScriptObjectEntityTotal = 0; - } -} - -void -cAudioManager::DestroyEntity(int32 id) -{ - if (m_bIsInitialised && id >= 0 && id < totalAudioEntitiesSlots && m_asAudioEntities[id].m_bIsUsed) { - m_asAudioEntities[id].m_bIsUsed = false; - for (int32 i = 0; i < m_nAudioEntitiesTotal; ++i) { - if (id == m_anAudioEntityIndices[i]) { - if (i < totalAudioEntitiesSlots - 1) - memmove(&m_anAudioEntityIndices[i], &m_anAudioEntityIndices[i + 1], NUM_AUDIOENTITY_EVENTS * (m_nAudioEntitiesTotal - (i + 1))); - m_anAudioEntityIndices[--m_nAudioEntitiesTotal] = totalAudioEntitiesSlots; - return; - } - } - } -} - -void -cAudioManager::DoJumboVolOffset() const -{ - if (!(m_FrameCounter % (m_anRandomTable[0] % 6 + 3))) - gJumboVolOffsetPercentage = m_anRandomTable[1] % 60; -} - -uint32 -cAudioManager::GetPlayerTalkSfx(int16 sound) -{ - uint32 sfx; - static uint32 lastSfx = NO_SAMPLE; - - switch (sound) { - case SOUND_PED_DAMAGE: - GetPhrase(&sfx, &lastSfx, SFX_CLAUDE_HIGH_DAMAGE_GRUNT_1, 11); - break; - case SOUND_PED_HIT: - GetPhrase(&sfx, &lastSfx, SFX_CLAUDE_LOW_DAMAGE_GRUNT_1, 10); - break; - case SOUND_PED_LAND: - GetPhrase(&sfx, &lastSfx, SFX_CLAUDE_HIT_GROUND_GRUNT_1, 6); - break; - default: - sfx = NO_SAMPLE; - break; - } - return sfx; -} - -uint32 -cAudioManager::GetCopTalkSfx(int16 sound) -{ - uint32 sfx; - PedState pedState; - static uint32 lastSfx = NO_SAMPLE; - - if (sound == SOUND_PED_ARREST_COP) { - GetPhrase(&sfx, &lastSfx, SFX_COP_VOICE_1_ARREST_1, 6); - } else { - if (sound != SOUND_PED_PURSUIT_COP) { - return GetGenericMaleTalkSfx(sound); - } - - pedState = FindPlayerPed()->m_nPedState; - if (pedState == PED_ARRESTED || pedState == PED_DEAD || pedState == PED_DIE) - return NO_SAMPLE; - GetPhrase(&sfx, &lastSfx, SFX_COP_VOICE_1_CHASE_1, 7); - } - - return (SFX_COP_VOICE_2_ARREST_1 - SFX_COP_VOICE_1_ARREST_1) * (m_sQueueSample.m_nEntityIndex % 5) + sfx; -} - -uint32 -cAudioManager::GetSwatTalkSfx(int16 sound) -{ - uint32 sfx; - PedState pedState; - static uint32 lastSfx = NO_SAMPLE; - - if (sound == SOUND_PED_ARREST_SWAT) { - GetPhrase(&sfx, &lastSfx, SFX_SWAT_VOICE_1_CHASE_1, 6); - } else { - if (sound != SOUND_PED_PURSUIT_SWAT) { - return GetGenericMaleTalkSfx(sound); - } - - pedState = FindPlayerPed()->m_nPedState; - if (pedState == PED_ARRESTED || pedState == PED_DEAD || pedState == PED_DIE) - return NO_SAMPLE; - GetPhrase(&sfx, &lastSfx, SFX_SWAT_VOICE_1_CHASE_1, 6); - } - - return (SFX_SWAT_VOICE_2_CHASE_1 - SFX_SWAT_VOICE_1_CHASE_1) * (m_sQueueSample.m_nEntityIndex % 4) + sfx; -} - -uint32 -cAudioManager::GetFBITalkSfx(int16 sound) -{ - uint32 sfx; - PedState pedState; - static uint32 lastSfx = NO_SAMPLE; - - if (sound == SOUND_PED_ARREST_FBI) { - GetPhrase(&sfx, &lastSfx, SFX_FBI_VOICE_1_CHASE_1, 6); - } else { - if (sound != SOUND_PED_PURSUIT_FBI) { - return GetGenericMaleTalkSfx(sound); - } - - pedState = FindPlayerPed()->m_nPedState; - if (pedState == PED_ARRESTED || pedState == PED_DEAD || pedState == PED_DIE) - return NO_SAMPLE; - GetPhrase(&sfx, &lastSfx, SFX_FBI_VOICE_1_CHASE_1, 6); - } - - return (SFX_FBI_VOICE_2_CHASE_1 - SFX_FBI_VOICE_1_CHASE_1) * (m_sQueueSample.m_nEntityIndex % 3) + sfx; -} - -uint32 -cAudioManager::GetArmyTalkSfx(int16 sound) -{ - uint32 sfx; - PedState pedState; - static uint32 lastSfx = NO_SAMPLE; - - if (sound != SOUND_PED_PURSUIT_ARMY) { - return GetGenericMaleTalkSfx(sound); - } - - pedState = FindPlayerPed()->m_nPedState; - if (pedState == PED_ARRESTED || pedState == PED_DEAD || pedState == PED_DIE) - return NO_SAMPLE; - GetPhrase(&sfx, &lastSfx, SFX_ARMY_VOICE_1_CHASE_1, 15); - - return (SFX_ARMY_VOICE_2_CHASE_1 - SFX_ARMY_VOICE_1_CHASE_1) * (m_sQueueSample.m_nEntityIndex % 2) + sfx; -} - -uint32 -cAudioManager::GetMedicTalkSfx(int16 sound) -{ - uint32 sfx; - static uint32 lastSfx = NO_SAMPLE; - - switch (sound) { - case SOUND_PED_HANDS_COWER: - GetPhrase(&sfx, &lastSfx, SFX_MEDIC_VOICE_1_GUN_PANIC_1, 5); - break; - case SOUND_PED_CAR_JACKED: - GetPhrase(&sfx, &lastSfx, SFX_MEDIC_VOICE_1_CARJACKED_1, 5); - break; - case SOUND_PED_HEALING: - GetPhrase(&sfx, &lastSfx, SFX_MEDIC_VOICE_1_AT_VICTIM_1, 12); - break; - case SOUND_PED_LEAVE_VEHICLE: - GetPhrase(&sfx, &lastSfx, SFX_MEDIC_VOICE_1_GET_OUT_VAN_CHAT_1, 9); - break; - case SOUND_PED_FLEE_RUN: - GetPhrase(&sfx, &lastSfx, SFX_MEDIC_VOICE_1_RUN_FROM_FIGHT_1, 6); - break; - default: - return GetGenericMaleTalkSfx(sound); - } - return (SFX_MEDIC_VOICE_2_GUN_PANIC_1 - SFX_MEDIC_VOICE_1_GUN_PANIC_1) * (m_sQueueSample.m_nEntityIndex % 2) + sfx; -} - -uint32 -cAudioManager::GetFiremanTalkSfx(int16 sound) -{ - return GetGenericMaleTalkSfx(sound); -} - -uint32 -cAudioManager::GetNormalMaleTalkSfx(int16 sound) -{ - uint32 sfx; - static uint32 lastSfx = NO_SAMPLE; - - switch (sound) { - case SOUND_PED_HANDS_COWER: - GetPhrase(&sfx, &lastSfx, SFX_NORMAL_MALE_GUN_PANIC_1, 7); - break; - case SOUND_PED_CAR_JACKED: - GetPhrase(&sfx, &lastSfx, SFX_NORMAL_MALE_CARJACKED_1, 7); - break; - case SOUND_PED_EVADE: - GetPhrase(&sfx, &lastSfx, SFX_NORMAL_MALE_DODGE_1, 9); - break; - case SOUND_PED_FLEE_RUN: - GetPhrase(&sfx, &lastSfx, SFX_NORMAL_MALE_RUN_FROM_FIGHT_1, 5); - break; - case SOUND_PED_CAR_COLLISION: - GetPhrase(&sfx, &lastSfx, SFX_NORMAL_MALE_DRIVER_ABUSE_1, 12); - break; - case SOUND_PED_CHAT_SEXY: - GetPhrase(&sfx, &lastSfx, SFX_NORMAL_MALE_EYING_1, 8); - break; - case SOUND_PED_CHAT_EVENT: - GetPhrase(&sfx, &lastSfx, SFX_NORMAL_MALE_SHOCKED_1, 10); - break; - case SOUND_PED_CHAT: - GetPhrase(&sfx, &lastSfx, SFX_NORMAL_MALE_CHAT_1, 25); - break; - default: - return GetGenericMaleTalkSfx(sound); - } - return sfx; -} - -uint32 -cAudioManager::GetTaxiDriverTalkSfx(int16 sound) -{ - uint32 sfx; - static uint32 lastSfx = NO_SAMPLE; - - if (sound == SOUND_PED_CAR_JACKED) { - GetPhrase(&sfx, &lastSfx, SFX_ASIAN_TAXI_DRIVER_VOICE_1_CARJACKED_1, 7); - } else { - if (sound != SOUND_PED_CAR_COLLISION) - return GetGenericMaleTalkSfx(sound); - GetPhrase(&sfx, &lastSfx, SFX_ASIAN_TAXI_DRIVER_VOICE_1_DRIVER_ABUSE_1, 6); - } - return (SFX_ASIAN_TAXI_DRIVER_VOICE_2_DRIVER_ABUSE_1 - SFX_ASIAN_TAXI_DRIVER_VOICE_1_DRIVER_ABUSE_1) * (m_sQueueSample.m_nEntityIndex % 2) + sfx; -} - -uint32 -cAudioManager::GetPimpTalkSfx(int16 sound) -{ - uint32 sfx; - static uint32 lastSfx = NO_SAMPLE; - - switch (sound) { - case SOUND_PED_HANDS_UP: - GetPhrase(&sfx, &lastSfx, SFX_PIMP_GUN_COOL_1, 7); - break; - case SOUND_PED_CAR_JACKED: - GetPhrase(&sfx, &lastSfx, SFX_PIMP_CARJACKED_1, 4); - break; - case SOUND_PED_DEFEND: - GetPhrase(&sfx, &lastSfx, SFX_PIMP_FIGHT_1, 9); - break; - case SOUND_PED_EVADE: - GetPhrase(&sfx, &lastSfx, SFX_PIMP_DODGE_1, 6); - break; - case SOUND_PED_CAR_COLLISION: - GetPhrase(&sfx, &lastSfx, SFX_PIMP_DRIVER_ABUSE_1, 5); - break; - case SOUND_PED_CHAT_EVENT: - GetPhrase(&sfx, &lastSfx, SFX_PIMP_SHOCKED_1, 2); - break; - case SOUND_PED_CHAT: - GetPhrase(&sfx, &lastSfx, SFX_PIMP_CHAT_1, 17); - break; - default: - return GetGenericMaleTalkSfx(sound); - } - return sfx; -} - -uint32 -cAudioManager::GetMafiaTalkSfx(int16 sound) -{ - uint32 sfx; - static uint32 lastSfx = NO_SAMPLE; - - switch (sound) { - case SOUND_PED_CAR_JACKING: - GetPhrase(&sfx, &lastSfx, SFX_MAFIA_MALE_VOICE_1_CARJACKING_1, 2); - break; - case SOUND_PED_CAR_JACKED: - GetPhrase(&sfx, &lastSfx, SFX_MAFIA_MALE_VOICE_1_CARJACKED_1, 2); - break; - case SOUND_PED_ATTACK: - GetPhrase(&sfx, &lastSfx, SFX_MAFIA_MALE_VOICE_1_FIGHT_1, 5); - break; - case SOUND_PED_EVADE: - GetPhrase(&sfx, &lastSfx, SFX_MAFIA_MALE_VOICE_1_DODGE_1, 5); - break; - case SOUND_PED_CAR_COLLISION: - GetPhrase(&sfx, &lastSfx, SFX_MAFIA_MALE_VOICE_1_DRIVER_ABUSE_1, 6); - break; - case SOUND_PED_CHAT_SEXY: - GetPhrase(&sfx, &lastSfx, SFX_MAFIA_MALE_VOICE_1_EYING_1, 3); - break; - case SOUND_PED_CHAT: - GetPhrase(&sfx, &lastSfx, SFX_MAFIA_MALE_VOICE_1_CHAT_1, 7); - break; - default: - return GetGenericMaleTalkSfx(sound); - } - return (SFX_MAFIA_MALE_VOICE_2_DRIVER_ABUSE_1 - SFX_MAFIA_MALE_VOICE_1_DRIVER_ABUSE_1) * (m_sQueueSample.m_nEntityIndex % 3) + sfx; -} - -uint32 -cAudioManager::GetTriadTalkSfx(int16 sound) -{ - uint32 sfx; - static uint32 lastSfx = NO_SAMPLE; - - switch (sound) { - case SOUND_PED_HANDS_UP: - GetPhrase(&sfx, &lastSfx, SFX_TRIAD_MALE_VOICE_1_GUN_COOL_1, 3); - break; - case SOUND_PED_CAR_JACKING: - GetPhrase(&sfx, &lastSfx, SFX_TRIAD_MALE_VOICE_1_CARJACKING_1, 2); - break; - case SOUND_PED_CAR_JACKED: - GetPhrase(&sfx, &lastSfx, SFX_TRIAD_MALE_VOICE_1_CARJACKED_1, 2); - break; - case SOUND_PED_ATTACK: - GetPhrase(&sfx, &lastSfx, SFX_TRIAD_MALE_VOICE_1_FIGHT_1, 5); - break; - case SOUND_PED_EVADE: - GetPhrase(&sfx, &lastSfx, SFX_TRIAD_MALE_VOICE_1_DODGE_1, 4); - break; - case SOUND_PED_CAR_COLLISION: - GetPhrase(&sfx, &lastSfx, SFX_TRIAD_MALE_VOICE_1_DRIVER_ABUSE_1, 7); - break; - case SOUND_PED_CHAT_SEXY: - GetPhrase(&sfx, &lastSfx, SFX_TRIAD_MALE_VOICE_1_EYING_1, 3); - break; - case SOUND_PED_CHAT: - GetPhrase(&sfx, &lastSfx, SFX_TRIAD_MALE_VOICE_1_CHAT_1, 8); - break; - default: - return GetGenericMaleTalkSfx(sound); - } - return sfx; -} - -uint32 -cAudioManager::GetDiabloTalkSfx(int16 sound) -{ - uint32 sfx; - static uint32 lastSfx = NO_SAMPLE; - - switch (sound) { - case SOUND_PED_HANDS_UP: - GetPhrase(&sfx, &lastSfx, SFX_DIABLO_MALE_VOICE_1_GUN_COOL_1, 4); - break; - case SOUND_PED_HANDS_COWER: - sound = SOUND_PED_FLEE_SPRINT; - return GetGenericMaleTalkSfx(sound); - break; - case SOUND_PED_CAR_JACKING: - GetPhrase(&sfx, &lastSfx, SFX_DIABLO_MALE_VOICE_1_CARJACKING_1, 2); - break; - case SOUND_PED_CAR_JACKED: - GetPhrase(&sfx, &lastSfx, SFX_DIABLO_MALE_VOICE_1_CARJACKED_1, 2); - break; - case SOUND_PED_ATTACK: - GetPhrase(&sfx, &lastSfx, SFX_DIABLO_MALE_VOICE_1_FIGHT_1, 4); - break; - case SOUND_PED_EVADE: - GetPhrase(&sfx, &lastSfx, SFX_DIABLO_MALE_VOICE_1_DODGE_1, 4); - break; - case SOUND_PED_CAR_COLLISION: - GetPhrase(&sfx, &lastSfx, SFX_DIABLO_MALE_VOICE_1_DRIVER_ABUSE_1, 5); - break; - case SOUND_PED_CHAT_SEXY: - GetPhrase(&sfx, &lastSfx, SFX_DIABLO_MALE_VOICE_1_EYING_1, 4); - break; - case SOUND_PED_CHAT: - GetPhrase(&sfx, &lastSfx, SFX_DIABLO_MALE_VOICE_1_CHAT_1, 5); - break; - default: - return GetGenericMaleTalkSfx(sound); - } - return (SFX_DIABLO_MALE_VOICE_2_CHAT_1 - SFX_DIABLO_MALE_VOICE_1_CHAT_1) * (m_sQueueSample.m_nEntityIndex % 2) + sfx; -} - -uint32 -cAudioManager::GetYakuzaTalkSfx(int16 sound) -{ - uint32 sfx; - static uint32 lastSfx = NO_SAMPLE; - - switch (sound) { - case SOUND_PED_CAR_JACKING: - GetPhrase(&sfx, &lastSfx, SFX_YAKUZA_MALE_VOICE_1_CARJACKING_1, 2); - break; - case SOUND_PED_CAR_JACKED: - GetPhrase(&sfx, &lastSfx, SFX_YAKUZA_MALE_VOICE_1_CARJACKED_1, 2); - break; - case SOUND_PED_ATTACK: - GetPhrase(&sfx, &lastSfx, SFX_YAKUZA_MALE_VOICE_1_FIGHT_1, 5); - break; - case SOUND_PED_EVADE: - GetPhrase(&sfx, &lastSfx, SFX_YAKUZA_MALE_VOICE_1_DODGE_1, 4); - break; - case SOUND_PED_CAR_COLLISION: - GetPhrase(&sfx, &lastSfx, SFX_YAKUZA_MALE_VOICE_1_DRIVER_ABUSE_1, 6); - break; - case SOUND_PED_CHAT: - GetPhrase(&sfx, &lastSfx, SFX_YAKUZA_MALE_VOICE_1_CHAT_1, 5); - break; - default: - return GetGenericMaleTalkSfx(sound); - } - return (SFX_YAKUZA_MALE_VOICE_2_DRIVER_ABUSE_1 - SFX_YAKUZA_MALE_VOICE_1_DRIVER_ABUSE_1) * (m_sQueueSample.m_nEntityIndex % 2) + sfx; -} - -uint32 -cAudioManager::GetYardieTalkSfx(int16 sound) -{ - uint32 sfx; - static uint32 lastSfx = NO_SAMPLE; - - switch (sound) { - case SOUND_PED_HANDS_UP: - sfx = SFX_YARDIE_MALE_VOICE_1_GUN_COOL_1; - break; - case SOUND_PED_CAR_JACKING: - GetPhrase(&sfx, &lastSfx, SFX_YARDIE_MALE_VOICE_1_CARJACKING_1, 2); - break; - case SOUND_PED_CAR_JACKED: - sfx = SFX_YARDIE_MALE_VOICE_1_CARJACKED_1; - break; - case SOUND_PED_ATTACK: - GetPhrase(&sfx, &lastSfx, SFX_YARDIE_MALE_VOICE_1_FIGHT_1, 6); - break; - case SOUND_PED_EVADE: - GetPhrase(&sfx, &lastSfx, SFX_YARDIE_MALE_VOICE_1_DODGE_1, 5); - break; - case SOUND_PED_CAR_COLLISION: - GetPhrase(&sfx, &lastSfx, SFX_YARDIE_MALE_VOICE_1_DRIVER_ABUSE_1, 6); - break; - case SOUND_PED_CHAT_SEXY: - GetPhrase(&sfx, &lastSfx, SFX_YARDIE_MALE_VOICE_1_EYING_1, 2); - break; - case SOUND_PED_CHAT: - GetPhrase(&sfx, &lastSfx, SFX_YARDIE_MALE_VOICE_1_CHAT_1, 8); - break; - default: - return GetGenericMaleTalkSfx(sound); - } - return (SFX_YARDIE_MALE_VOICE_2_DRIVER_ABUSE_1 - SFX_YARDIE_MALE_VOICE_1_DRIVER_ABUSE_1) * (m_sQueueSample.m_nEntityIndex % 2) + sfx; -} - -uint32 -cAudioManager::GetColumbianTalkSfx(int16 sound) -{ - uint32 sfx; - static uint32 lastSfx = NO_SAMPLE; - - switch (sound) { - case SOUND_PED_CAR_JACKING: - GetPhrase(&sfx, &lastSfx, SFX_COLUMBIAN_MALE_VOICE_1_CARJACKING_1, 2); - break; - case SOUND_PED_CAR_JACKED: - GetPhrase(&sfx, &lastSfx, SFX_COLUMBIAN_MALE_VOICE_1_CARJACKED_1, 2); - break; - case SOUND_PED_ATTACK: - GetPhrase(&sfx, &lastSfx, SFX_COLUMBIAN_MALE_VOICE_1_FIGHT_1, 5); - break; - case SOUND_PED_EVADE: - GetPhrase(&sfx, &lastSfx, SFX_COLUMBIAN_MALE_VOICE_1_DODGE_1, 5); - break; - case SOUND_PED_CAR_COLLISION: - GetPhrase(&sfx, &lastSfx, SFX_COLUMBIAN_MALE_VOICE_1_DRIVER_ABUSE_1, 6); - break; - case SOUND_PED_CHAT_SEXY: - GetPhrase(&sfx, &lastSfx, SFX_COLUMBIAN_MALE_VOICE_1_EYING_1, 2); - break; - case SOUND_PED_CHAT: - GetPhrase(&sfx, &lastSfx, SFX_COLUMBIAN_MALE_VOICE_1_CHAT_1, 5); - break; - default: - return GetGenericMaleTalkSfx(sound); - } - return (SFX_COLUMBIAN_MALE_VOICE_2_DRIVER_ABUSE_1 - SFX_COLUMBIAN_MALE_VOICE_1_DRIVER_ABUSE_1) * (m_sQueueSample.m_nEntityIndex % 2) + sfx; -} - -uint32 -cAudioManager::GetHoodTalkSfx(int16 sound) -{ - uint32 sfx; - static uint32 lastSfx = NO_SAMPLE; - - switch (sound) { - case SOUND_PED_HANDS_UP: - GetPhrase(&sfx, &lastSfx, SFX_HOOD_MALE_VOICE_1_GUN_COOL_1, 5); - break; - case SOUND_PED_CAR_JACKING: - GetPhrase(&sfx, &lastSfx, SFX_HOOD_MALE_VOICE_1_CARJACKING_1, 2); - break; - case SOUND_PED_CAR_JACKED: - GetPhrase(&sfx, &lastSfx, SFX_HOOD_MALE_VOICE_1_CARJACKED_1, 2); - break; - case SOUND_PED_ATTACK: - GetPhrase(&sfx, &lastSfx, SFX_HOOD_MALE_VOICE_1_FIGHT_1, 6); - break; - case SOUND_PED_EVADE: - GetPhrase(&sfx, &lastSfx, SFX_HOOD_MALE_VOICE_1_DODGE_1, 5); - break; - case SOUND_PED_CAR_COLLISION: - GetPhrase(&sfx, &lastSfx, SFX_HOOD_MALE_VOICE_1_DRIVER_ABUSE_1, 7); - break; - case SOUND_PED_CHAT_SEXY: - GetPhrase(&sfx, &lastSfx, SFX_HOOD_MALE_VOICE_1_EYING_1, 2); - break; - case SOUND_PED_CHAT: - GetPhrase(&sfx, &lastSfx, SFX_HOOD_MALE_VOICE_1_CHAT_1, 6); - break; - - default: - return GetGenericMaleTalkSfx(sound); - break; - } - return (SFX_HOOD_MALE_VOICE_2_DRIVER_ABUSE_1 - SFX_HOOD_MALE_VOICE_1_DRIVER_ABUSE_1) * (m_sQueueSample.m_nEntityIndex % 2) + sfx; -} - -uint32 -cAudioManager::GetBlackCriminalTalkSfx(int16 sound) -{ - uint32 sfx; - static uint32 lastSfx = NO_SAMPLE; - - switch (sound) { - case SOUND_PED_HANDS_UP: - GetPhrase(&sfx, &lastSfx, SFX_BLACK_CRIMINAL_VOICE_1_GUN_COOL_1, 4); - break; - case SOUND_PED_CAR_JACKING: - sfx = SFX_BLACK_CRIMINAL_VOICE_1_CARJACKING_1; - break; - case SOUND_PED_MUGGING: - GetPhrase(&sfx, &lastSfx, SFX_BLACK_CRIMINAL_VOICE_1_MUGGING_1, 2); - break; - case SOUND_PED_ATTACK: - GetPhrase(&sfx, &lastSfx, SFX_BLACK_CRIMINAL_VOICE_1_FIGHT_1, 5); - break; - case SOUND_PED_EVADE: - GetPhrase(&sfx, &lastSfx, SFX_BLACK_CRIMINAL_VOICE_1_DODGE_1, 6); - break; - case SOUND_PED_CAR_COLLISION: - GetPhrase(&sfx, &lastSfx, SFX_BLACK_CRIMINAL_VOICE_1_DRIVER_ABUSE_1, 5); - break; - default: - return GetGenericMaleTalkSfx(sound); - break; - } - return sfx; -} - -uint32 -cAudioManager::GetWhiteCriminalTalkSfx(int16 sound) -{ - uint32 sfx; - static uint32 lastSfx = NO_SAMPLE; - - switch (sound) { - case SOUND_PED_HANDS_UP: - GetPhrase(&sfx, &lastSfx, SFX_WHITE_CRIMINAL_VOICE_1_GUN_COOL_1, 3); - break; - case SOUND_PED_CAR_JACKING: - sfx = SFX_WHITE_CRIMINAL_VOICE_1_CARJACKING_1; - break; - case SOUND_PED_MUGGING: - GetPhrase(&sfx, &lastSfx, SFX_WHITE_CRIMINAL_VOICE_1_MUGGING_1, 2); - break; - case SOUND_PED_ATTACK: - GetPhrase(&sfx, &lastSfx, SFX_WHITE_CRIMINAL_VOICE_1_FIGHT_1, 4); - break; - case SOUND_PED_EVADE: - GetPhrase(&sfx, &lastSfx, SFX_WHITE_CRIMINAL_VOICE_1_DODGE_1, 5); - break; - case SOUND_PED_CAR_COLLISION: - GetPhrase(&sfx, &lastSfx, SFX_WHITE_CRIMINAL_VOICE_1_DRIVER_ABUSE_1, 4); - break; - default: - return GetGenericMaleTalkSfx(sound); - break; - } - return sfx; -} - -uint32 -cAudioManager::GetMaleNo2TalkSfx(int16 sound) -{ - uint32 sfx; - static uint32 lastSfx = NO_SAMPLE; - - switch (sound) { - case SOUND_PED_CAR_JACKED: - GetPhrase(&sfx, &lastSfx, SFX_CASUAL_MALE_OLD_VOICE_1_CARJACKED_1, 3); - break; - case SOUND_PED_ROBBED: - GetPhrase(&sfx, &lastSfx, SFX_CASUAL_MALE_OLD_VOICE_1_MUGGED_1, 4); - break; - case SOUND_PED_ATTACK: - GetPhrase(&sfx, &lastSfx, SFX_CASUAL_MALE_OLD_VOICE_1_FIGHT_1, 4); - break; - case SOUND_PED_EVADE: - GetPhrase(&sfx, &lastSfx, SFX_CASUAL_MALE_OLD_VOICE_1_DODGE_1, 4); - break; - case SOUND_PED_CAR_COLLISION: - GetPhrase(&sfx, &lastSfx, SFX_CASUAL_MALE_OLD_VOICE_1_DRIVER_ABUSE_1, 7); - break; - case SOUND_PED_CHAT_SEXY: - GetPhrase(&sfx, &lastSfx, SFX_CASUAL_MALE_OLD_VOICE_1_EYING_1, 5); - break; - case SOUND_PED_CHAT: - GetPhrase(&sfx, &lastSfx, SFX_CASUAL_MALE_OLD_VOICE_1_CHAT_1, 7); - break; - default: - return GetGenericMaleTalkSfx(sound); - } - return sfx; -} - -uint32 -cAudioManager::GetBlackProjectMaleTalkSfx(int16 sound, int32 model) -{ - uint32 sfx; - static uint32 lastSfx = NO_SAMPLE; - - switch (sound) { - case SOUND_PED_HANDS_UP: - GetPhrase(&sfx, &lastSfx, SFX_BLACK_PROJECT_MALE_VOICE_1_GUN_COOL_1, 3); - break; - case SOUND_PED_CAR_JACKED: - GetPhrase(&sfx, &lastSfx, SFX_BLACK_PROJECT_MALE_VOICE_1_CARJACKED_1, 2); - break; - case SOUND_PED_ROBBED: - GetPhrase(&sfx, &lastSfx, SFX_BLACK_PROJECT_MALE_VOICE_1_MUGGED_1, 2); - break; - case SOUND_PED_ATTACK: - GetPhrase(&sfx, &lastSfx, SFX_BLACK_PROJECT_MALE_VOICE_1_FIGHT_1, 6); - break; - case SOUND_PED_EVADE: - GetPhrase(&sfx, &lastSfx, SFX_BLACK_PROJECT_MALE_VOICE_1_DODGE_1, 5); - break; - case SOUND_PED_CAR_COLLISION: - GetPhrase(&sfx, &lastSfx, SFX_BLACK_PROJECT_MALE_VOICE_1_DRIVER_ABUSE_1, 7); - break; - case SOUND_PED_CHAT_SEXY: - GetPhrase(&sfx, &lastSfx, SFX_BLACK_PROJECT_MALE_VOICE_1_EYING_1, 3); - break; - case SOUND_PED_CHAT: - GetPhrase(&sfx, &lastSfx, SFX_BLACK_PROJECT_MALE_VOICE_1_CHAT_1, 6); - default: - return GetGenericMaleTalkSfx(sound); - } - -// TODO(MIAMI): just making this compile -// if (model == MI_P_MAN2) -// sfx += (SFX_BLACK_PROJECT_MALE_VOICE_2_DRIVER_ABUSE_1 - SFX_BLACK_PROJECT_MALE_VOICE_1_DRIVER_ABUSE_1); - return sfx; -} - -uint32 -cAudioManager::GetWhiteFatMaleTalkSfx(int16 sound) -{ - uint32 sfx; - static uint32 lastSfx = NO_SAMPLE; - - switch (sound) { - case SOUND_PED_CAR_JACKED: - GetPhrase(&sfx, &lastSfx, SFX_WHITE_FAT_MALE_VOICE_1_CARJACKED_1, 3); - break; - case SOUND_PED_ROBBED: - GetPhrase(&sfx, &lastSfx, SFX_WHITE_FAT_MALE_VOICE_1_MUGGED_1, 3); - break; - case SOUND_PED_EVADE: - GetPhrase(&sfx, &lastSfx, SFX_WHITE_FAT_MALE_VOICE_1_DODGE_1, 9); - break; - case SOUND_PED_CAR_COLLISION: - GetPhrase(&sfx, &lastSfx, SFX_WHITE_FAT_MALE_VOICE_1_DRIVER_ABUSE_1, 9); - break; - case SOUND_PED_WAIT_DOUBLEBACK: - GetPhrase(&sfx, &lastSfx, SFX_WHITE_FAT_MALE_VOICE_1_LOST_1, 2); - break; - case SOUND_PED_CHAT: - GetPhrase(&sfx, &lastSfx, SFX_WHITE_FAT_MALE_VOICE_1_CHAT_1, 9); - default: - return GetGenericMaleTalkSfx(sound); - } - return sfx; -} - -uint32 -cAudioManager::GetBlackFatMaleTalkSfx(int16 sound) -{ - uint32 sfx; - static uint32 lastSfx = NO_SAMPLE; - - switch (sound) { - case SOUND_PED_CAR_JACKED: - GetPhrase(&sfx, &lastSfx, SFX_BLACK_FAT_MALE_VOICE_1_CARJACKED_1, 4); - break; - case SOUND_PED_ROBBED: - GetPhrase(&sfx, &lastSfx, SFX_BLACK_FAT_MALE_VOICE_1_MUGGED_1, 3); - break; - case SOUND_PED_EVADE: - GetPhrase(&sfx, &lastSfx, SFX_BLACK_FAT_MALE_VOICE_1_DODGE_1, 7); - break; - case SOUND_PED_CAR_COLLISION: - GetPhrase(&sfx, &lastSfx, SFX_BLACK_FAT_MALE_VOICE_1_DRIVER_ABUSE_1, 6); - break; - case SOUND_PED_WAIT_DOUBLEBACK: - GetPhrase(&sfx, &lastSfx, SFX_BLACK_FAT_MALE_VOICE_1_LOST_1, 3); - break; - case SOUND_PED_CHAT: - GetPhrase(&sfx, &lastSfx, SFX_BLACK_FAT_MALE_VOICE_1_CHAT_1, 8); - break; - default: - return GetGenericMaleTalkSfx(sound); - } - return sfx; -} - -uint32 -cAudioManager::GetBlackCasualFemaleTalkSfx(int16 sound) -{ - uint32 sfx; - static uint32 lastSfx = NO_SAMPLE; - - switch (sound) { - case SOUND_PED_HANDS_COWER: - GetPhrase(&sfx, &lastSfx, SFX_FEMALE_1_VOICE_1_GUN_PANIC_1, 2); - break; - case SOUND_PED_CAR_JACKED: - GetPhrase(&sfx, &lastSfx, SFX_FEMALE_1_VOICE_1_CARJACKED_1, 2); - break; - case SOUND_PED_ROBBED: - GetPhrase(&sfx, &lastSfx, SFX_FEMALE_1_VOICE_1_MUGGED_1, 3); - break; - case SOUND_PED_EVADE: - GetPhrase(&sfx, &lastSfx, SFX_FEMALE_1_VOICE_1_DODGE_1, 6); - break; - case SOUND_PED_FLEE_RUN: - GetPhrase(&sfx, &lastSfx, SFX_FEMALE_1_VOICE_1_RUN_FROM_FIGHT_1, 2); - break; - case SOUND_PED_CAR_COLLISION: - GetPhrase(&sfx, &lastSfx, SFX_FEMALE_1_VOICE_1_DRIVER_ABUSE_1, 7); - break; - case SOUND_PED_CHAT_EVENT: - GetPhrase(&sfx, &lastSfx, SFX_FEMALE_1_VOICE_1_SHOCKED_1, 4); - break; - case SOUND_PED_CHAT: - GetPhrase(&sfx, &lastSfx, SFX_FEMALE_1_VOICE_1_CHAT_1, 8); - break; - default: - return GetGenericFemaleTalkSfx(sound); - } - return sfx; -} - -uint32 -cAudioManager::GetWhiteCasualFemaleTalkSfx(int16 sound) -{ - uint32 sfx; - static uint32 lastSfx = NO_SAMPLE; - - switch (sound) { - case SOUND_PED_HANDS_COWER: - GetPhrase(&sfx, &lastSfx, SFX_WHITE_CASUAL_FEMALE_VOICE_1_GUN_PANIC_1, 2); - break; - case SOUND_PED_CAR_JACKED: - GetPhrase(&sfx, &lastSfx, SFX_WHITE_CASUAL_FEMALE_VOICE_1_CARJACKED_1, 2); - break; - case SOUND_PED_ROBBED: - sfx = SFX_WHITE_CASUAL_FEMALE_VOICE_1_MUGGED_1; - break; - case SOUND_PED_EVADE: - GetPhrase(&sfx, &lastSfx, SFX_WHITE_CASUAL_FEMALE_VOICE_1_DODGE_1, 3); - break; - case SOUND_PED_FLEE_RUN: - GetPhrase(&sfx, &lastSfx, SFX_WHITE_CASUAL_FEMALE_VOICE_1_RUN_FROM_FIGHT_1, 2); - break; - case SOUND_PED_CAR_COLLISION: - GetPhrase(&sfx, &lastSfx, SFX_WHITE_CASUAL_FEMALE_VOICE_1_DRIVER_ABUSE_1, 8); - break; - case SOUND_PED_CHAT_EVENT: - GetPhrase(&sfx, &lastSfx, SFX_WHITE_CASUAL_FEMALE_VOICE_1_SHOCKED_1, 2); - break; - case SOUND_PED_CHAT: - GetPhrase(&sfx, &lastSfx, SFX_WHITE_CASUAL_FEMALE_VOICE_1_CHAT_1, 4); - break; - default: - return GetGenericFemaleTalkSfx(sound); - } - return sfx; -} - -uint32 -cAudioManager::GetFemaleNo3TalkSfx(int16 sound) -{ - uint32 sfx; - static uint32 lastSfx = NO_SAMPLE; - - switch (sound) { - case SOUND_PED_HANDS_COWER: - GetPhrase(&sfx, &lastSfx, SFX_FEMALE_3_VOICE_1_GUN_PANIC_1, 5); - break; - case SOUND_PED_CAR_JACKED: - GetPhrase(&sfx, &lastSfx, SFX_FEMALE_3_VOICE_1_CARJACKED_1, 3); - break; - case SOUND_PED_ROBBED: - GetPhrase(&sfx, &lastSfx, SFX_FEMALE_3_VOICE_1_MUGGED_1, 3); - break; - case SOUND_PED_EVADE: - GetPhrase(&sfx, &lastSfx, SFX_FEMALE_3_VOICE_1_DODGE_1, 6); - break; - case SOUND_PED_FLEE_RUN: - GetPhrase(&sfx, &lastSfx, SFX_FEMALE_3_VOICE_1_RUN_FROM_FIGHT_1, 4); - break; - case SOUND_PED_CAR_COLLISION: - GetPhrase(&sfx, &lastSfx, SFX_FEMALE_3_VOICE_1_DRIVER_ABUSE_1, 6); - break; - case SOUND_PED_CHAT_EVENT: - GetPhrase(&sfx, &lastSfx, SFX_FEMALE_3_VOICE_1_SHOCKED_1, 4); - break; - case SOUND_PED_CHAT: - GetPhrase(&sfx, &lastSfx, SFX_FEMALE_3_VOICE_1_CHAT_1, 5); - break; - default: - return GetGenericFemaleTalkSfx(sound); - } - return sfx; -} - -uint32 -cAudioManager::GetBlackFatFemaleTalkSfx(int16 sound) -{ - uint32 sfx; - static uint32 lastSfx = NO_SAMPLE; - - switch (sound) { - case SOUND_PED_HANDS_COWER: - GetPhrase(&sfx, &lastSfx, SFX_BLACK_FAT_FEMALE_VOICE_1_GUN_PANIC_1, 4); - break; - case SOUND_PED_CAR_JACKED: - GetPhrase(&sfx, &lastSfx, SFX_BLACK_FAT_FEMALE_VOICE_1_CARJACKED_1, 2); - break; - case SOUND_PED_ROBBED: - GetPhrase(&sfx, &lastSfx, SFX_BLACK_FAT_FEMALE_VOICE_1_MUGGED_1, 2); - break; - case SOUND_PED_EVADE: - GetPhrase(&sfx, &lastSfx, SFX_BLACK_FAT_FEMALE_VOICE_1_DODGE_1, 5); - break; - case SOUND_PED_CAR_COLLISION: - GetPhrase(&sfx, &lastSfx, SFX_BLACK_FAT_FEMALE_VOICE_1_DRIVER_ABUSE_1, 6); - break; - case SOUND_PED_CHAT_EVENT: - GetPhrase(&sfx, &lastSfx, SFX_BLACK_FAT_FEMALE_VOICE_1_SHOCKED_1, 5); - break; - case SOUND_PED_CHAT: - GetPhrase(&sfx, &lastSfx, SFX_BLACK_FAT_FEMALE_VOICE_1_CHAT_1, 7); - break; - default: - return GetGenericFemaleTalkSfx(sound); - } - return sfx; -} - -uint32 -cAudioManager::GetWhiteFatFemaleTalkSfx(int16 sound) -{ - uint32 sfx; - static uint32 lastSfx = NO_SAMPLE; - - switch (sound) { - case SOUND_PED_CAR_JACKED: - GetPhrase(&sfx, &lastSfx, SFX_WHITE_FAT_FEMALE_VOICE_1_CARJACKED_1, 2); - break; - case SOUND_PED_ROBBED: - GetPhrase(&sfx, &lastSfx, SFX_WHITE_FAT_FEMALE_VOICE_1_MUGGED_1, 2); - break; - case SOUND_PED_EVADE: - GetPhrase(&sfx, &lastSfx, SFX_WHITE_FAT_FEMALE_VOICE_1_DODGE_1, 6); - break; - case SOUND_PED_CAR_COLLISION: - GetPhrase(&sfx, &lastSfx, SFX_WHITE_FAT_FEMALE_VOICE_1_DRIVER_ABUSE_1, 8); - break; - case SOUND_PED_WAIT_DOUBLEBACK: - GetPhrase(&sfx, &lastSfx, SFX_WHITE_FAT_FEMALE_VOICE_1_LOST_1, 2); - break; - case SOUND_PED_CHAT_EVENT: - GetPhrase(&sfx, &lastSfx, SFX_WHITE_FAT_FEMALE_VOICE_1_SHOCKED_1, 4); - break; - case SOUND_PED_CHAT: - GetPhrase(&sfx, &lastSfx, SFX_WHITE_FAT_FEMALE_VOICE_1_CHAT_1, 8); - break; - default: - return GetGenericFemaleTalkSfx(sound); - } - return sfx; -} - -uint32 -cAudioManager::GetBlackFemaleProstituteTalkSfx(int16 sound) -{ - uint32 sfx; - static uint32 lastSfx = NO_SAMPLE; - - switch (sound) { - case SOUND_PED_HANDS_UP: - GetPhrase(&sfx, &lastSfx, SFX_BLACK_PROSTITUTE_VOICE_1_GUN_COOL_1, 4); - break; - case SOUND_PED_ROBBED: - sfx = SFX_BLACK_PROSTITUTE_VOICE_1_MUGGED_1; - break; - case SOUND_PED_ATTACK: - GetPhrase(&sfx, &lastSfx, SFX_BLACK_PROSTITUTE_VOICE_1_FIGHT_1, 4); - break; - case SOUND_PED_EVADE: - GetPhrase(&sfx, &lastSfx, SFX_BLACK_PROSTITUTE_VOICE_1_DODGE_1, 3); - break; - case SOUND_PED_CAR_COLLISION: - GetPhrase(&sfx, &lastSfx, SFX_BLACK_PROSTITUTE_VOICE_1_DRIVER_ABUSE_1, 4); - break; - case SOUND_PED_SOLICIT: - GetPhrase(&sfx, &lastSfx, SFX_BLACK_PROSTITUTE_VOICE_1_SOLICIT_1, 8); - break; - case SOUND_PED_CHAT: - GetPhrase(&sfx, &lastSfx, SFX_BLACK_PROSTITUTE_VOICE_1_CHAT_1, 4); - break; - default: - return GetGenericFemaleTalkSfx(sound); - } - return (SFX_BLACK_PROSTITUTE_VOICE_2_CHAT_1 - SFX_BLACK_PROSTITUTE_VOICE_1_CHAT_1) * (m_sQueueSample.m_nEntityIndex % 2) + sfx; -} - -uint32 -cAudioManager::GetWhiteFemaleProstituteTalkSfx(int16 sound) -{ - uint32 sfx; - static uint32 lastSfx = NO_SAMPLE; - - switch (sound) { - case SOUND_PED_ROBBED: - GetPhrase(&sfx, &lastSfx, SFX_WHITE_PROSTITUTE_VOICE_1_MUGGED_1, 2); - break; - case SOUND_PED_ATTACK: - GetPhrase(&sfx, &lastSfx, SFX_WHITE_PROSTITUTE_VOICE_1_FIGHT_1, 4); - break; - case SOUND_PED_EVADE: - GetPhrase(&sfx, &lastSfx, SFX_WHITE_PROSTITUTE_VOICE_1_DODGE_1, 3); - break; - case SOUND_PED_CAR_COLLISION: - GetPhrase(&sfx, &lastSfx, SFX_WHITE_PROSTITUTE_VOICE_1_DRIVER_ABUSE_1, 4); - break; - case SOUND_PED_SOLICIT: - GetPhrase(&sfx, &lastSfx, SFX_WHITE_PROSTITUTE_VOICE_1_SOLICIT_1, 8); - break; - case SOUND_PED_CHAT: - GetPhrase(&sfx, &lastSfx, SFX_WHITE_PROSTITUTE_VOICE_1_CHAT_1, 4); - break; - default: - return GetGenericFemaleTalkSfx(sound); - } - return (SFX_WHITE_PROSTITUTE_VOICE_2_CHAT_1 - SFX_WHITE_PROSTITUTE_VOICE_1_CHAT_1) * (m_sQueueSample.m_nEntityIndex % 2) + sfx; -} - -uint32 -cAudioManager::GetBlackProjectFemaleOldTalkSfx(int16 sound) -{ - uint32 sfx; - static uint32 lastSfx = NO_SAMPLE; - - switch (sound) { - case SOUND_PED_CAR_JACKED: - GetPhrase(&sfx, &lastSfx, SFX_BLACK_PROJECT_FEMALE_OLD_VOICE_1_CARJACKED_1, 6); - break; - case SOUND_PED_ROBBED: - GetPhrase(&sfx, &lastSfx, SFX_BLACK_PROJECT_FEMALE_OLD_VOICE_1_MUGGED_1, 2); - break; - case SOUND_PED_EVADE: - GetPhrase(&sfx, &lastSfx, SFX_BLACK_PROJECT_FEMALE_OLD_VOICE_1_DODGE_1, 10); - break; - case SOUND_PED_FLEE_RUN: - GetPhrase(&sfx, &lastSfx, SFX_BLACK_PROJECT_FEMALE_OLD_VOICE_1_RUN_FROM_FIGHT_1, 6); - break; - case SOUND_PED_CAR_COLLISION: - GetPhrase(&sfx, &lastSfx, SFX_BLACK_PROJECT_FEMALE_OLD_VOICE_1_DRIVER_ABUSE_1, 7); - break; - case SOUND_PED_CHAT_EVENT: - GetPhrase(&sfx, &lastSfx, SFX_BLACK_PROJECT_FEMALE_OLD_VOICE_1_SHOCKED_1, 2); - break; - case SOUND_PED_CHAT: - GetPhrase(&sfx, &lastSfx, SFX_BLACK_PROJECT_FEMALE_OLD_VOICE_1_CHAT_1, 10); - break; - default: - return GetGenericFemaleTalkSfx(sound); - } - return sfx; -} - -uint32 -cAudioManager::GetBlackProjectFemaleYoungTalkSfx(int16 sound) -{ - uint32 sfx; - static uint32 lastSfx = NO_SAMPLE; - - switch (sound) { - case SOUND_PED_HANDS_COWER: - GetPhrase(&sfx, &lastSfx, SFX_BLACK_PROJECT_FEMALE_YOUNG_VOICE_1_GUN_PANIC_1, 4); - break; - case SOUND_PED_CAR_JACKED: - sfx = SFX_BLACK_PROJECT_FEMALE_YOUNG_VOICE_1_CARJACKED_1; - break; - case SOUND_PED_ROBBED: - GetPhrase(&sfx, &lastSfx, SFX_BLACK_PROJECT_FEMALE_YOUNG_VOICE_1_MUGGED_1, 2); - break; - case SOUND_PED_EVADE: - GetPhrase(&sfx, &lastSfx, SFX_BLACK_PROJECT_FEMALE_YOUNG_VOICE_1_DODGE_1, 5); - break; - case SOUND_PED_CAR_COLLISION: - GetPhrase(&sfx, &lastSfx, SFX_BLACK_PROJECT_FEMALE_YOUNG_VOICE_1_DRIVER_ABUSE_1, 6); - break; - case SOUND_PED_CHAT_EVENT: - GetPhrase(&sfx, &lastSfx, SFX_BLACK_PROJECT_FEMALE_YOUNG_VOICE_1_SHOCKED_1, 5); - break; - case SOUND_PED_CHAT: - GetPhrase(&sfx, &lastSfx, SFX_BLACK_PROJECT_FEMALE_YOUNG_VOICE_1_CHAT_1, 7); - break; - default: - return GetGenericFemaleTalkSfx(sound); - } - return sfx; -} - -uint32 -cAudioManager::GetChinatownMaleOldTalkSfx(int16 sound) -{ - uint32 sfx; - static uint32 lastSfx = NO_SAMPLE; - - switch (sound) { - case SOUND_PED_HANDS_COWER: - GetPhrase(&sfx, &lastSfx, SFX_CHINATOWN_MALE_OLD_VOICE_1_GUN_PANIC_1, 3); - break; - case SOUND_PED_CAR_JACKED: - GetPhrase(&sfx, &lastSfx, SFX_CHINATOWN_MALE_OLD_VOICE_1_CARJACKED_1, 2); - break; - case SOUND_PED_ATTACK: - GetPhrase(&sfx, &lastSfx, SFX_CHINATOWN_MALE_OLD_VOICE_1_FIGHT_1, 5); - break; - case SOUND_PED_EVADE: - GetPhrase(&sfx, &lastSfx, SFX_CHINATOWN_MALE_OLD_VOICE_1_DODGE_1, 6); - break; - case SOUND_PED_CAR_COLLISION: - GetPhrase(&sfx, &lastSfx, SFX_CHINATOWN_MALE_OLD_VOICE_1_DRIVER_ABUSE_1, 6); - break; - case SOUND_PED_CHAT_SEXY: - GetPhrase(&sfx, &lastSfx, SFX_CHINATOWN_MALE_OLD_VOICE_1_EYING_1, 3); - break; - case SOUND_PED_CHAT: - GetPhrase(&sfx, &lastSfx, SFX_CHINATOWN_MALE_OLD_VOICE_1_CHAT_1, 7); - break; - default: - return GetGenericMaleTalkSfx(sound); - } - return sfx; -} - -uint32 -cAudioManager::GetChinatownMaleYoungTalkSfx(int16 sound) -{ - uint32 sfx; - static uint32 lastSfx = NO_SAMPLE; - - switch (sound) { - case SOUND_PED_HANDS_COWER: - GetPhrase(&sfx, &lastSfx, SFX_CHINATOWN_MALE_YOUNG_VOICE_1_GUN_PANIC_1, 2); - break; - case SOUND_PED_CAR_JACKED: - GetPhrase(&sfx, &lastSfx, SFX_CHINATOWN_MALE_YOUNG_VOICE_1_CARJACKED_1, 2); - break; - case SOUND_PED_ATTACK: - GetPhrase(&sfx, &lastSfx, SFX_CHINATOWN_MALE_YOUNG_VOICE_1_FIGHT_1, 6); - break; - case SOUND_PED_EVADE: - GetPhrase(&sfx, &lastSfx, SFX_CHINATOWN_MALE_YOUNG_VOICE_1_DODGE_1, 5); - break; - case SOUND_PED_CAR_COLLISION: - GetPhrase(&sfx, &lastSfx, SFX_CHINATOWN_MALE_YOUNG_VOICE_1_DRIVER_ABUSE_1, 6); - break; - case SOUND_PED_CHAT_SEXY: - GetPhrase(&sfx, &lastSfx, SFX_CHINATOWN_MALE_YOUNG_VOICE_1_EYING_1, 3); - break; - case SOUND_PED_CHAT: - GetPhrase(&sfx, &lastSfx, SFX_CHINATOWN_MALE_YOUNG_VOICE_1_CHAT_1, 6); - break; - default: - return GetGenericMaleTalkSfx(sound); - } - return sfx; -} - -uint32 -cAudioManager::GetChinatownFemaleOldTalkSfx(int16 sound) -{ - uint32 sfx; - static uint32 lastSfx = NO_SAMPLE; - - switch (sound) { - case SOUND_PED_HANDS_COWER: - GetPhrase(&sfx, &lastSfx, SFX_CHINATOWN_OLD_FEMALE_VOICE_1_GUN_PANIC_1, 3); - break; - case SOUND_PED_ROBBED: - GetPhrase(&sfx, &lastSfx, SFX_CHINATOWN_OLD_FEMALE_VOICE_1_MUGGED_1, 2); - break; - case SOUND_PED_EVADE: - GetPhrase(&sfx, &lastSfx, SFX_CHINATOWN_OLD_FEMALE_VOICE_1_DODGE_1, 5); - break; - case SOUND_PED_CAR_COLLISION: - GetPhrase(&sfx, &lastSfx, SFX_CHINATOWN_OLD_FEMALE_VOICE_1_DRIVER_ABUSE_1, 5); - break; - case SOUND_PED_CHAT_EVENT: - sfx = SFX_CHINATOWN_OLD_FEMALE_VOICE_1_SHOCKED_1; - break; - case SOUND_PED_CHAT: - GetPhrase(&sfx, &lastSfx, SFX_CHINATOWN_OLD_FEMALE_VOICE_1_CHAT_1, 6); - break; - default: - return GetGenericFemaleTalkSfx(sound); - } - return sfx; -} - -uint32 -cAudioManager::GetChinatownFemaleYoungTalkSfx(int16 sound) -{ - uint32 sfx; - static uint32 lastSfx = NO_SAMPLE; - - switch (sound) { - case SOUND_PED_CAR_JACKED: - GetPhrase(&sfx, &lastSfx, SFX_CHINATOWN_YOUNG_FEMALE_VOICE_1_CARJACKED_1, 2); - break; - case SOUND_PED_ROBBED: - GetPhrase(&sfx, &lastSfx, SFX_CHINATOWN_YOUNG_FEMALE_VOICE_1_MUGGED_1, 2); - break; - case SOUND_PED_EVADE: - GetPhrase(&sfx, &lastSfx, SFX_CHINATOWN_YOUNG_FEMALE_VOICE_1_DODGE_1, 6); - break; - case SOUND_PED_CAR_COLLISION: - GetPhrase(&sfx, &lastSfx, SFX_CHINATOWN_YOUNG_FEMALE_VOICE_1_DRIVER_ABUSE_1, 7); - break; - case SOUND_PED_CHAT_EVENT: - GetPhrase(&sfx, &lastSfx, SFX_CHINATOWN_YOUNG_FEMALE_VOICE_1_SHOCKED_1, 4); - break; - case SOUND_PED_CHAT: - GetPhrase(&sfx, &lastSfx, SFX_CHINATOWN_YOUNG_FEMALE_VOICE_1_CHAT_1, 7); - break; - default: - return GetGenericFemaleTalkSfx(sound); - } - return sfx; -} - -uint32 -cAudioManager::GetLittleItalyMaleTalkSfx(int16 sound) -{ - uint32 sfx; - static uint32 lastSfx = NO_SAMPLE; - - switch (sound) { - case SOUND_PED_HANDS_COWER: - GetPhrase(&sfx, &lastSfx, SFX_LITTLE_ITALY_MALE_VOICE_1_GUN_PANIC_1, 3); - break; - case SOUND_PED_CAR_JACKED: - GetPhrase(&sfx, &lastSfx, SFX_LITTLE_ITALY_MALE_VOICE_1_CARJACKED_1, 2); - break; - case SOUND_PED_ROBBED: - GetPhrase(&sfx, &lastSfx, SFX_LITTLE_ITALY_MALE_VOICE_1_MUGGED_1, 2); - break; - case SOUND_PED_ATTACK: - GetPhrase(&sfx, &lastSfx, SFX_LITTLE_ITALY_MALE_VOICE_1_FIGHT_1, 5); - break; - case SOUND_PED_EVADE: - GetPhrase(&sfx, &lastSfx, SFX_LITTLE_ITALY_MALE_VOICE_1_DODGE_1, 5); - break; - case SOUND_PED_CAR_COLLISION: - GetPhrase(&sfx, &lastSfx, SFX_LITTLE_ITALY_MALE_VOICE_1_DRIVER_ABUSE_1, 7); - break; - case SOUND_PED_CHAT: - GetPhrase(&sfx, &lastSfx, SFX_LITTLE_ITALY_MALE_VOICE_1_CHAT_1, 6); - break; - default: - return GetGenericMaleTalkSfx(sound); - } - return (SFX_LITTLE_ITALY_MALE_VOICE_2_DRIVER_ABUSE_1 - SFX_LITTLE_ITALY_MALE_VOICE_1_DRIVER_ABUSE_1) * (m_sQueueSample.m_nEntityIndex % 2) + sfx; -} - -uint32 -cAudioManager::GetLittleItalyFemaleOldTalkSfx(int16 sound) -{ - uint32 sfx; - static uint32 lastSfx = NO_SAMPLE; - - switch (sound) { - case SOUND_PED_CAR_JACKED: - GetPhrase(&sfx, &lastSfx, SFX_LITTLE_ITALY_OLD_FEMALE_VOICE_1_CARJACKED_1, 2); - break; - case SOUND_PED_ROBBED: - GetPhrase(&sfx, &lastSfx, SFX_LITTLE_ITALY_OLD_FEMALE_VOICE_1_MUGGED_1, 2); - break; - case SOUND_PED_EVADE: - GetPhrase(&sfx, &lastSfx, SFX_LITTLE_ITALY_OLD_FEMALE_VOICE_1_DODGE_1, 6); - break; - case SOUND_PED_CAR_COLLISION: - GetPhrase(&sfx, &lastSfx, SFX_LITTLE_ITALY_OLD_FEMALE_VOICE_1_DRIVER_ABUSE_1, 7); - break; - case SOUND_PED_CHAT_EVENT: - GetPhrase(&sfx, &lastSfx, SFX_LITTLE_ITALY_OLD_FEMALE_VOICE_1_SHOCKED_1, 4); - break; - case SOUND_PED_CHAT: - GetPhrase(&sfx, &lastSfx, SFX_LITTLE_ITALY_OLD_FEMALE_VOICE_1_CHAT_1, 7); - break; - default: - return GetGenericFemaleTalkSfx(sound); - } - return sfx; -} - -uint32 -cAudioManager::GetLittleItalyFemaleYoungTalkSfx(int16 sound) -{ - uint32 sfx; - static uint32 lastSfx = NO_SAMPLE; - - switch (sound) { - case SOUND_PED_CAR_JACKED: - GetPhrase(&sfx, &lastSfx, SFX_LITTLE_ITALY_YOUNG_FEMALE_VOICE_1_CARJACKED_1, 2); - break; - case SOUND_PED_ROBBED: - GetPhrase(&sfx, &lastSfx, SFX_LITTLE_ITALY_YOUNG_FEMALE_VOICE_1_MUGGED_1, 2); - break; - case SOUND_PED_EVADE: - GetPhrase(&sfx, &lastSfx, SFX_LITTLE_ITALY_YOUNG_FEMALE_VOICE_1_DODGE_1, 7); - break; - case SOUND_PED_CAR_COLLISION: - GetPhrase(&sfx, &lastSfx, SFX_LITTLE_ITALY_YOUNG_FEMALE_VOICE_1_DRIVER_ABUSE_1, 6); - break; - case SOUND_PED_CHAT_EVENT: - GetPhrase(&sfx, &lastSfx, SFX_LITTLE_ITALY_YOUNG_FEMALE_VOICE_1_SHOCKED_1, 4); - break; - case SOUND_PED_CHAT: - GetPhrase(&sfx, &lastSfx, SFX_LITTLE_ITALY_YOUNG_FEMALE_VOICE_1_CHAT_1, 6); - break; - default: - return GetGenericFemaleTalkSfx(sound); - } - return sfx; -} - -uint32 -cAudioManager::GetWhiteDockerMaleTalkSfx(int16 sound) -{ - uint32 sfx; - static uint32 lastSfx = NO_SAMPLE; - - switch (sound) { - case SOUND_PED_HANDS_COWER: - GetPhrase(&sfx, &lastSfx, SFX_WHITE_DOCKER_MALE_VOICE_1_GUN_PANIC_1, 2); - break; - case SOUND_PED_ATTACK: - GetPhrase(&sfx, &lastSfx, SFX_WHITE_DOCKER_MALE_VOICE_1_FIGHT_1, 3); - break; - case SOUND_PED_EVADE: - GetPhrase(&sfx, &lastSfx, SFX_WHITE_DOCKER_MALE_VOICE_1_DODGE_1, 4); - break; - case SOUND_PED_CAR_COLLISION: - GetPhrase(&sfx, &lastSfx, SFX_WHITE_DOCKER_MALE_VOICE_1_DRIVER_ABUSE_1, 4); - break; - case SOUND_PED_CHAT_SEXY: - GetPhrase(&sfx, &lastSfx, SFX_WHITE_DOCKER_MALE_VOICE_1_EYING_1, 3); - break; - case SOUND_PED_CHAT: - GetPhrase(&sfx, &lastSfx, SFX_WHITE_DOCKER_MALE_VOICE_1_CHAT_1, 5); - break; - default: - return GetGenericMaleTalkSfx(sound); - } - return sfx; -} - -uint32 -cAudioManager::GetBlackDockerMaleTalkSfx(int16 sound) -{ - uint32 sfx; - static uint32 lastSfx = NO_SAMPLE; - - switch (sound) { - case SOUND_PED_HANDS_COWER: - GetPhrase(&sfx, &lastSfx, SFX_BLACK_DOCKER_VOICE_1_GUN_PANIC_1, 3); - break; - case SOUND_PED_ATTACK: - GetPhrase(&sfx, &lastSfx, SFX_BLACK_DOCKER_VOICE_1_FIGHT_1, 5); - break; - case SOUND_PED_EVADE: - GetPhrase(&sfx, &lastSfx, SFX_BLACK_DOCKER_VOICE_1_DODGE_1, 5); - break; - case SOUND_PED_CAR_COLLISION: - GetPhrase(&sfx, &lastSfx, SFX_BLACK_DOCKER_VOICE_1_DRIVER_ABUSE_1, 6); - break; - case SOUND_PED_CHAT_SEXY: - GetPhrase(&sfx, &lastSfx, SFX_BLACK_DOCKER_VOICE_1_EYING_1, 3); - break; - case SOUND_PED_CHAT: - GetPhrase(&sfx, &lastSfx, SFX_BLACK_DOCKER_VOICE_1_CHAT_1, 5); - break; - default: - return GetGenericMaleTalkSfx(sound); - } - return sfx; -} - -uint32 -cAudioManager::GetScumMaleTalkSfx(int16 sound) -{ - uint32 sfx; - static uint32 lastSfx = NO_SAMPLE; - - switch (sound) { - case SOUND_PED_HANDS_COWER: - GetPhrase(&sfx, &lastSfx, SFX_SCUM_MALE_VOICE_1_GUN_PANIC_1, 5); - break; - case SOUND_PED_ROBBED: - sfx = SFX_SCUM_MALE_VOICE_1_MUGGED_1; - break; - case SOUND_PED_ATTACK: - GetPhrase(&sfx, &lastSfx, SFX_SCUM_MALE_VOICE_1_FIGHT_1, 10); - break; - case SOUND_PED_EVADE: - GetPhrase(&sfx, &lastSfx, SFX_SCUM_MALE_VOICE_1_DODGE_1, 5); - break; - case SOUND_PED_CAR_COLLISION: - GetPhrase(&sfx, &lastSfx, SFX_SCUM_MALE_VOICE_1_DRIVER_ABUSE_1, 6); - break; - case SOUND_PED_WAIT_DOUBLEBACK: - GetPhrase(&sfx, &lastSfx, SFX_SCUM_MALE_VOICE_1_LOST_1, 3); - break; - case SOUND_PED_CHAT_SEXY: - GetPhrase(&sfx, &lastSfx, SFX_SCUM_MALE_VOICE_1_EYING_1, 5); - break; - case SOUND_PED_CHAT: - GetPhrase(&sfx, &lastSfx, SFX_SCUM_MALE_VOICE_1_CHAT_1, 9); - break; - default: - return GetGenericMaleTalkSfx(sound); - } - return sfx; -} - -uint32 -cAudioManager::GetScumFemaleTalkSfx(int16 sound) -{ - uint32 sfx; - static uint32 lastSfx = NO_SAMPLE; - - switch (sound) { - case SOUND_PED_HANDS_COWER: - GetPhrase(&sfx, &lastSfx, SFX_SCUM_FEMALE_VOICE_1_GUN_PANIC_1, 4); - break; - case SOUND_PED_ROBBED: - GetPhrase(&sfx, &lastSfx, SFX_SCUM_FEMALE_VOICE_1_MUGGED_1, 2); - break; - case SOUND_PED_ATTACK: - GetPhrase(&sfx, &lastSfx, SFX_SCUM_FEMALE_VOICE_1_FIGHT_1, 4); - break; - case SOUND_PED_EVADE: - GetPhrase(&sfx, &lastSfx, SFX_SCUM_FEMALE_VOICE_1_DODGE_1, 8); - break; - case SOUND_PED_CAR_COLLISION: - GetPhrase(&sfx, &lastSfx, SFX_SCUM_FEMALE_VOICE_1_DRIVER_ABUSE_1, 5); - break; - case SOUND_PED_CHAT: - GetPhrase(&sfx, &lastSfx, SFX_SCUM_FEMALE_VOICE_1_CHAT_1, 13); - break; - default: - return GetGenericFemaleTalkSfx(sound); - } - return sfx; -} - -uint32 -cAudioManager::GetWhiteWorkerMaleTalkSfx(int16 sound) -{ - uint32 sfx; - static uint32 lastSfx = NO_SAMPLE; - - switch (sound) { - case SOUND_PED_HANDS_COWER: - GetPhrase(&sfx, &lastSfx, SFX_WHITE_WORKER_MALE_VOICE_1_GUN_PANIC_1, 3); - break; - case SOUND_PED_ATTACK: - GetPhrase(&sfx, &lastSfx, SFX_WHITE_WORKER_MALE_VOICE_1_FIGHT_1, 3); - break; - case SOUND_PED_EVADE: - GetPhrase(&sfx, &lastSfx, SFX_WHITE_WORKER_MALE_VOICE_1_DODGE_1, 4); - break; - case SOUND_PED_CAR_COLLISION: - GetPhrase(&sfx, &lastSfx, SFX_WHITE_WORKER_MALE_VOICE_1_DRIVER_ABUSE_1, 6); - break; - case SOUND_PED_CHAT_SEXY: - GetPhrase(&sfx, &lastSfx, SFX_WHITE_WORKER_MALE_VOICE_1_EYING_1, 2); - break; - case SOUND_PED_CHAT: - GetPhrase(&sfx, &lastSfx, SFX_WHITE_WORKER_MALE_VOICE_1_CHAT_1, 6); - break; - default: - return GetGenericMaleTalkSfx(sound); - } - return sfx; -} - -uint32 -cAudioManager::GetBlackWorkerMaleTalkSfx(int16 sound) -{ - uint32 sfx; - static uint32 lastSfx = NO_SAMPLE; - - switch (sound) { - case SOUND_PED_HANDS_COWER: - GetPhrase(&sfx, &lastSfx, SFX_BLACK_WORKER_MALE_VOICE_1_GUN_PANIC_1, 4); - break; - case SOUND_PED_ATTACK: - GetPhrase(&sfx, &lastSfx, SFX_BLACK_WORKER_MALE_VOICE_1_FIGHT_1, 3); - break; - case SOUND_PED_EVADE: - GetPhrase(&sfx, &lastSfx, SFX_BLACK_WORKER_MALE_VOICE_1_DODGE_1, 3); - break; - case SOUND_PED_CAR_COLLISION: - GetPhrase(&sfx, &lastSfx, SFX_BLACK_WORKER_MALE_VOICE_1_DRIVER_ABUSE_1, 4); - break; - case SOUND_PED_CHAT_SEXY: - GetPhrase(&sfx, &lastSfx, SFX_BLACK_WORKER_MALE_VOICE_1_EYING_1, 3); - break; - case SOUND_PED_CHAT: - GetPhrase(&sfx, &lastSfx, SFX_BLACK_WORKER_MALE_VOICE_1_CHAT_1, 4); - break; - default: - return GetGenericMaleTalkSfx(sound); - } - return sfx; -} - -uint32 -cAudioManager::GetBusinessMaleYoungTalkSfx(int16 sound, int32 model) -{ - uint32 sfx; - static uint32 lastSfx = NO_SAMPLE; - - switch (sound) { - case SOUND_PED_HANDS_COWER: - GetPhrase(&sfx, &lastSfx, SFX_BUSINESS_MALE_YOUNG_VOICE_1_GUN_PANIC_1, 3); - break; - case SOUND_PED_CAR_JACKED: - GetPhrase(&sfx, &lastSfx, SFX_BUSINESS_MALE_YOUNG_VOICE_1_CARJACKED_1, 2); - break; - case SOUND_PED_ROBBED: - GetPhrase(&sfx, &lastSfx, SFX_BUSINESS_MALE_YOUNG_VOICE_1_MUGGED_1, 2); - break; - case SOUND_PED_ATTACK: - GetPhrase(&sfx, &lastSfx, SFX_BUSINESS_MALE_YOUNG_VOICE_1_FIGHT_1, 4); - break; - case SOUND_PED_EVADE: - GetPhrase(&sfx, &lastSfx, SFX_BUSINESS_MALE_YOUNG_VOICE_1_DODGE_1, 4); - break; - case SOUND_PED_FLEE_RUN: - GetPhrase(&sfx, &lastSfx, SFX_BUSINESS_MALE_YOUNG_VOICE_1_RUN_FROM_FIGHT_1, 5); - break; - case SOUND_PED_CAR_COLLISION: - GetPhrase(&sfx, &lastSfx, SFX_BUSINESS_MALE_YOUNG_VOICE_1_DRIVER_ABUSE_1, 6); - break; - case SOUND_PED_CHAT: - GetPhrase(&sfx, &lastSfx, SFX_BUSINESS_MALE_YOUNG_VOICE_1_CHAT_1, 6); - break; - default: - return GetGenericMaleTalkSfx(sound); - } - -// TODO(MIAMI): just making this compile -// if (model == MI_B_MAN3) -// sfx += (SFX_BUSINESS_MALE_YOUNG_VOICE_2_DRIVER_ABUSE_1 - SFX_BUSINESS_MALE_YOUNG_VOICE_1_DRIVER_ABUSE_1); - return sfx; -} - -uint32 -cAudioManager::GetBusinessMaleOldTalkSfx(int16 sound) -{ - uint32 sfx; - static uint32 lastSfx = NO_SAMPLE; - - switch (sound) { - case SOUND_PED_HANDS_COWER: - GetPhrase(&sfx, &lastSfx, SFX_BUSINESS_MALE_OLD_VOICE_1_GUN_PANIC_1, 3); - break; - case SOUND_PED_CAR_JACKED: - GetPhrase(&sfx, &lastSfx, SFX_BUSINESS_MALE_OLD_VOICE_1_CARJACKED_1, 2); - break; - case SOUND_PED_ROBBED: - GetPhrase(&sfx, &lastSfx, SFX_BUSINESS_MALE_OLD_VOICE_1_MUGGED_1, 2); - break; - case SOUND_PED_ATTACK: - GetPhrase(&sfx, &lastSfx, SFX_BUSINESS_MALE_OLD_VOICE_1_FIGHT_1, 5); - break; - case SOUND_PED_EVADE: - GetPhrase(&sfx, &lastSfx, SFX_BUSINESS_MALE_OLD_VOICE_1_DODGE_1, 4); - break; - case SOUND_PED_FLEE_RUN: - GetPhrase(&sfx, &lastSfx, SFX_BUSINESS_MALE_OLD_VOICE_1_MRUN_FROM_FIGHT_1, 5); - break; - case SOUND_PED_CAR_COLLISION: - GetPhrase(&sfx, &lastSfx, SFX_BUSINESS_MALE_OLD_VOICE_1_DRIVER_ABUSE_1, 5); - break; - case SOUND_PED_CHAT: - GetPhrase(&sfx, &lastSfx, SFX_BUSINESS_MALE_OLD_VOICE_1_CHAT_1, 5); - break; - default: - return GetGenericMaleTalkSfx(sound); - } - return sfx; -} - -uint32 -cAudioManager::GetWhiteBusinessFemaleTalkSfx(int16 sound, int32 model) -{ - uint32 sfx; - static uint32 lastSfx = NO_SAMPLE; - - switch (sound) { - case SOUND_PED_HANDS_COWER: - GetPhrase(&sfx, &lastSfx, SFX_WHITE_BUSINESS_FEMALE_VOICE_1_GUN_PANIC_1, 4); - break; - case SOUND_PED_CAR_JACKED: - GetPhrase(&sfx, &lastSfx, SFX_WHITE_BUSINESS_FEMALE_VOICE_1_CARJACKED_1, 2); - break; - case SOUND_PED_ROBBED: - GetPhrase(&sfx, &lastSfx, SFX_WHITE_BUSINESS_FEMALE_VOICE_1_MUGGED_1, 2); - break; - case SOUND_PED_EVADE: - GetPhrase(&sfx, &lastSfx, SFX_WHITE_BUSINESS_FEMALE_VOICE_1_DODGE_1, 6); - break; - case SOUND_PED_FLEE_RUN: - GetPhrase(&sfx, &lastSfx, SFX_WHITE_BUSINESS_FEMALE_VOICE_1_RUN_FROM_FIGHT_1, 4); - break; - case SOUND_PED_CAR_COLLISION: - GetPhrase(&sfx, &lastSfx, SFX_WHITE_BUSINESS_FEMALE_VOICE_1_DRIVER_ABUSE_1, 5); - break; - case SOUND_PED_CHAT_EVENT: - GetPhrase(&sfx, &lastSfx, SFX_WHITE_BUSINESS_FEMALE_VOICE_1_SHOCKED_1, 4); - break; - case SOUND_PED_CHAT: - GetPhrase(&sfx, &lastSfx, SFX_WHITE_BUSINESS_FEMALE_VOICE_1_CHAT_1, 7); - break; - default: - return GetGenericFemaleTalkSfx(sound); - } - -// TODO(MIAMI): just making this compile -// if (model == MI_B_WOM2) -// sfx += (SFX_WHITE_BUSINESS_FEMALE_VOICE_2_DRIVER_ABUSE_1 - SFX_WHITE_BUSINESS_FEMALE_VOICE_1_DRIVER_ABUSE_1); - return sfx; -} - -uint32 -cAudioManager::GetBlackBusinessFemaleTalkSfx(int16 sound) -{ - uint32 sfx; - static uint32 lastSfx = NO_SAMPLE; - - switch (sound) { - case SOUND_PED_HANDS_COWER: - GetPhrase(&sfx, &lastSfx, SFX_BLACK_BUSINESS_FEMALE_VOICE_1_GUN_PANIC_1, 5); - break; - case SOUND_PED_CAR_JACKED: - GetPhrase(&sfx, &lastSfx, SFX_BLACK_BUSINESS_FEMALE_VOICE_1_CARAJACKED_1, 4); - break; - case SOUND_PED_ROBBED: - GetPhrase(&sfx, &lastSfx, SFX_BLACK_BUSINESS_FEMALE_VOICE_1_MUGGED_1, 3); - break; - case SOUND_PED_EVADE: - GetPhrase(&sfx, &lastSfx, SFX_BLACK_BUSINESS_FEMALE_VOICE_1_DODGE_1, 6); - break; - case SOUND_PED_FLEE_RUN: - GetPhrase(&sfx, &lastSfx, SFX_BLACK_BUSINESS_FEMALE_VOICE_1_RUN_FROM_FIGHT_1, 6); - break; - case SOUND_PED_CAR_COLLISION: - GetPhrase(&sfx, &lastSfx, SFX_BLACK_BUSINESS_FEMALE_VOICE_1_DRIVER_ABUSE_1, 7); - break; - case SOUND_PED_CHAT_EVENT: - GetPhrase(&sfx, &lastSfx, SFX_BLACK_BUSINESS_FEMALE_VOICE_1_SHOCKED_1, 4); - break; - case SOUND_PED_CHAT: - GetPhrase(&sfx, &lastSfx, SFX_BLACK_BUSINESS_FEMALE_VOICE_1_CHAT_1, 7); - break; - default: - return GetGenericFemaleTalkSfx(sound); - } - return sfx; -} - -uint32 -cAudioManager::GetSupermodelMaleTalkSfx(int16 sound) -{ - uint32 sfx; - static uint32 lastSfx = NO_SAMPLE; - - switch (sound) { - case SOUND_PED_CAR_JACKED: - GetPhrase(&sfx, &lastSfx, SFX_MODEL_MALE_VOICE_1_CARJACKED_1, 2); - break; - case SOUND_PED_ROBBED: - GetPhrase(&sfx, &lastSfx, SFX_MODEL_MALE_VOICE_1_MUGGED_1, 2); - break; - case SOUND_PED_ATTACK: - GetPhrase(&sfx, &lastSfx, SFX_MODEL_MALE_VOICE_1_FIGHT_1, 5); - break; - case SOUND_PED_EVADE: - GetPhrase(&sfx, &lastSfx, SFX_MODEL_MALE_VOICE_1_DODGE_1, 6); - break; - case SOUND_PED_CAR_COLLISION: - GetPhrase(&sfx, &lastSfx, SFX_MODEL_MALE_VOICE_1_DRIVER_ABUSE_1, 6); - break; - case SOUND_PED_CHAT_SEXY: - GetPhrase(&sfx, &lastSfx, SFX_MODEL_MALE_VOICE_1_EYING_1, 3); - break; - case SOUND_PED_CHAT: - GetPhrase(&sfx, &lastSfx, SFX_MODEL_MALE_VOICE_1_CHAT_1, 6); - break; - default: - return GetGenericMaleTalkSfx(sound); - } - return sfx; -} - -uint32 -cAudioManager::GetSupermodelFemaleTalkSfx(int16 sound) -{ - uint32 sfx; - static uint32 lastSfx = NO_SAMPLE; - - switch (sound) { - case SOUND_PED_HANDS_COWER: - GetPhrase(&sfx, &lastSfx, SFX_MODEL_FEMALE_VOICE_1_GUN_PANIC_1, 4); - break; - case SOUND_PED_ROBBED: - GetPhrase(&sfx, &lastSfx, SFX_MODEL_FEMALE_VOICE_1_MUGGED_1, 3); - break; - case SOUND_PED_EVADE: - GetPhrase(&sfx, &lastSfx, SFX_MODEL_FEMALE_VOICE_1_DODGE_1, 4); - break; - case SOUND_PED_CAR_COLLISION: - GetPhrase(&sfx, &lastSfx, SFX_MODEL_FEMALE_VOICE_1_DRIVER_ABUSE_1, 7); - break; - case SOUND_PED_CHAT_EVENT: - GetPhrase(&sfx, &lastSfx, SFX_MODEL_FEMALE_VOICE_1_SHOCKED_1, 5); - break; - case SOUND_PED_CHAT: - GetPhrase(&sfx, &lastSfx, SFX_MODEL_FEMALE_VOICE_1_CHAT_1, 8); - break; - default: - return GetGenericFemaleTalkSfx(sound); - } - return sfx; -} - -uint32 -cAudioManager::GetStewardMaleTalkSfx(int16 sound) -{ - uint32 sfx; - static uint32 lastSfx = NO_SAMPLE; - - switch (sound) { - case SOUND_PED_HANDS_COWER: - GetPhrase(&sfx, &lastSfx, SFX_STEWARD_MALE_VOICE_1_GUN_PANIC_1, 3); - break; - case SOUND_PED_ATTACK: - GetPhrase(&sfx, &lastSfx, SFX_STEWARD_MALE_VOICE_1_FIGHT_1, 4); - break; - case SOUND_PED_EVADE: - GetPhrase(&sfx, &lastSfx, SFX_STEWARD_MALE_VOICE_1_DODGE_1, 3); - break; - case SOUND_PED_CAR_COLLISION: - GetPhrase(&sfx, &lastSfx, SFX_STEWARD_MALE_VOICE_1_DRIVER_ABUSE_1, 5); - break; - case SOUND_PED_CHAT: - GetPhrase(&sfx, &lastSfx, SFX_STEWARD_MALE_VOICE_1_CHAT_1, 4); - break; - default: - return GetGenericMaleTalkSfx(sound); - } - return sfx; -} - -uint32 -cAudioManager::GetStewardFemaleTalkSfx(int16 sound) -{ - uint32 sfx; - static uint32 lastSfx = NO_SAMPLE; - - switch (sound) { - case SOUND_PED_HANDS_COWER: - GetPhrase(&sfx, &lastSfx, SFX_STEWARD_FEMALE_VOICE_1_GUN_PANIC_1, 3); - break; - case SOUND_PED_EVADE: - GetPhrase(&sfx, &lastSfx, SFX_STEWARD_FEMALE_VOICE_1_DODGE_1, 5); - break; - case SOUND_PED_CAR_COLLISION: - GetPhrase(&sfx, &lastSfx, SFX_STEWARD_FEMALE_VOICE_1_DRIVER_ABUSE_1, 5); - break; - case SOUND_PED_CHAT: - GetPhrase(&sfx, &lastSfx, SFX_STEWARD_FEMALE_VOICE_1_CHAT_1, 5); - break; - default: - return GetGenericFemaleTalkSfx(sound); - } - return (SFX_STEWARD_FEMALE_VOICE_2_DRIVER_ABUSE_1 - SFX_STEWARD_FEMALE_VOICE_1_DRIVER_ABUSE_1) * (m_sQueueSample.m_nEntityIndex % 2) + sfx; -} - -uint32 -cAudioManager::GetFanMaleTalkSfx(int16 sound, int32 model) -{ - uint32 sfx; - static uint32 lastSfx = NO_SAMPLE; - - switch (sound) { - case SOUND_PED_ATTACK: - GetPhrase(&sfx, &lastSfx, SFX_FOOTBALL_MALE_VOICE_1_FIGHT_1, 3); - break; - case SOUND_PED_EVADE: - GetPhrase(&sfx, &lastSfx, SFX_FOOTBALL_MALE_VOICE_1_DODGE_1, 4); - break; - case SOUND_PED_CAR_COLLISION: - GetPhrase(&sfx, &lastSfx, SFX_FOOTBALL_MALE_VOICE_1_DRIVER_ABUSE_1, 5); - break; - case SOUND_PED_CHAT_EVENT: - GetPhrase(&sfx, &lastSfx, SFX_FOOTBALL_MALE_VOICE_1_SHOCKED_1, 2); - break; - case SOUND_PED_CHAT: - GetPhrase(&sfx, &lastSfx, SFX_FOOTBALL_MALE_VOICE_1_CHAT_1, 6); - break; - default: - return GetGenericMaleTalkSfx(sound); - } - -// TODO(MIAMI): just making this compile -// if (model == MI_FAN_MAN2) -// sfx += (SFX_FOOTBALL_MALE_VOICE_2_DRIVER_ABUSE_1 - SFX_FOOTBALL_MALE_VOICE_1_DRIVER_ABUSE_1); - return sfx; -} - -uint32 -cAudioManager::GetFanFemaleTalkSfx(int16 sound) -{ - uint32 sfx; - static uint32 lastSfx = NO_SAMPLE; - - switch (sound) { - case SOUND_PED_ROBBED: - sfx = SFX_FOOTBALL_FEMALE_VOICE_1_MUGGED_1; - break; - case SOUND_PED_EVADE: - GetPhrase(&sfx, &lastSfx, SFX_FOOTBALL_FEMALE_VOICE_1_DODGE_1, 4); - break; - case SOUND_PED_CAR_COLLISION: - GetPhrase(&sfx, &lastSfx, SFX_FOOTBALL_FEMALE_VOICE_1_DRIVER_ABUSE_1, 5); - break; - case SOUND_PED_CHAT_EVENT: - GetPhrase(&sfx, &lastSfx, SFX_FOOTBALL_FEMALE_VOICE_1_SHOCKED_1, 2); - break; - case SOUND_PED_CHAT: - GetPhrase(&sfx, &lastSfx, SFX_FOOTBALL_FEMALE_VOICE_1_CHAT_1, 6); - break; - default: - return GetGenericFemaleTalkSfx(sound); - } - return (SFX_FOOTBALL_FEMALE_VOICE_2_DRIVER_ABUSE_1 - SFX_FOOTBALL_FEMALE_VOICE_1_DRIVER_ABUSE_1) * (m_sQueueSample.m_nEntityIndex % 2) + sfx; -} - -uint32 -cAudioManager::GetHospitalMaleTalkSfx(int16 sound) -{ - uint32 sfx; - static uint32 lastSfx = NO_SAMPLE; - - switch (sound) { - case SOUND_PED_HANDS_COWER: - GetPhrase(&sfx, &lastSfx, SFX_HOSPITAL_MALE_VOICE_1_GUN_PANIC_1, 4); - break; - case SOUND_PED_ATTACK: - GetPhrase(&sfx, &lastSfx, SFX_HOSPITAL_MALE_VOICE_1_FIGHT_1, 4); - break; - case SOUND_PED_EVADE: - GetPhrase(&sfx, &lastSfx, SFX_HOSPITAL_MALE_VOICE_1_DODGE_1, 4); - break; - case SOUND_PED_CAR_COLLISION: - GetPhrase(&sfx, &lastSfx, SFX_HOSPITAL_MALE_VOICE_1_DRIVER_ABUSE_1, 5); - break; - case SOUND_PED_CHAT: - GetPhrase(&sfx, &lastSfx, SFX_HOSPITAL_MALE_VOICE_1_CHAT_1, 5); - break; - default: - return GetGenericMaleTalkSfx(sound); - } - return sfx; -} - -uint32 -cAudioManager::GetHospitalFemaleTalkSfx(int16 sound) -{ - uint32 sfx; - static uint32 lastSfx = NO_SAMPLE; - - switch (sound) { - case SOUND_PED_EVADE: - GetPhrase(&sfx, &lastSfx, SFX_HOSPITAL_FEMALE_VOICE_1_DODGE_1, 5); - break; - case SOUND_PED_CAR_COLLISION: - GetPhrase(&sfx, &lastSfx, SFX_HOSPITAL_FEMALE_VOICE_1_DRIVER_ABUSE_1, 6); - break; - case SOUND_PED_CHAT: - GetPhrase(&sfx, &lastSfx, SFX_HOSPITAL_FEMALE_VOICE_1_CHAT_1, 6); - break; - default: - return GetGenericFemaleTalkSfx(sound); - } - return sfx; -} - -uint32 -cAudioManager::GetWhiteConstructionWorkerTalkSfx(int16 sound) -{ - uint32 sfx; - static uint32 lastSfx = NO_SAMPLE; - - switch (sound) { - case SOUND_PED_HANDS_COWER: - GetPhrase(&sfx, &lastSfx, SFX_WHITE_MALE_CONSTRUCTION_VOICE_1_GUN_PANIC_1, 3); - break; - case SOUND_PED_CAR_JACKED: - sfx = SFX_WHITE_MALE_CONSTRUCTION_VOICE_1_CARJACKED_1; - break; - case SOUND_PED_ATTACK: - GetPhrase(&sfx, &lastSfx, SFX_WHITE_MALE_CONSTRUCTION_VOICE_1_FIGHT_1, 5); - break; - case SOUND_PED_EVADE: - GetPhrase(&sfx, &lastSfx, SFX_WHITE_MALE_CONSTRUCTION_VOICE_1_DODGE_1, 5); - break; - case SOUND_PED_CAR_COLLISION: - GetPhrase(&sfx, &lastSfx, SFX_WHITE_MALE_CONSTRUCTION_VOICE_1_DRIVER_ABUSE_1, 4); - break; - case SOUND_PED_CHAT_SEXY: - GetPhrase(&sfx, &lastSfx, SFX_WHITE_MALE_CONSTRUCTION_VOICE_1_EYING_1, 3); - break; - case SOUND_PED_CHAT: - GetPhrase(&sfx, &lastSfx, SFX_WHITE_MALE_CONSTRUCTION_VOICE_1_CHAT_1, 7); - break; - default: - return GetGenericMaleTalkSfx(sound); - } - return sfx; -} - -uint32 -cAudioManager::GetBlackConstructionWorkerTalkSfx(int16 sound) -{ - uint32 sfx; - static uint32 lastSfx = NO_SAMPLE; - - switch (sound) { - case SOUND_PED_HANDS_COWER: - GetPhrase(&sfx, &lastSfx, SFX_BLACK_CONSTRUCTION_MALE_VOICE_1_GUN_PANIC_1, 3); - break; - case SOUND_PED_CAR_JACKED: - GetPhrase(&sfx, &lastSfx, SFX_BLACK_CONSTRUCTION_MALE_VOICE_1_CARJACKED_1, 2); - break; - case SOUND_PED_ATTACK: - GetPhrase(&sfx, &lastSfx, SFX_BLACK_CONSTRUCTION_MALE_VOICE_1_FIGHT_1, 5); - break; - case SOUND_PED_EVADE: - GetPhrase(&sfx, &lastSfx, SFX_BLACK_CONSTRUCTION_MALE_VOICE_1_DODGE_1, 5); - break; - case SOUND_PED_CAR_COLLISION: - GetPhrase(&sfx, &lastSfx, SFX_BLACK_CONSTRUCTION_MALE_VOICE_1_DRIVER_ABUSE_1, 5); - break; - case SOUND_PED_CHAT_SEXY: - GetPhrase(&sfx, &lastSfx, SFX_BLACK_CONSTRUCTION_MALE_VOICE_1_EYING_1, 4); - break; - case SOUND_PED_CHAT: - GetPhrase(&sfx, &lastSfx, SFX_BLACK_CONSTRUCTION_MALE_VOICE_1_CHAT_1, 4); - break; - default: - return GetGenericMaleTalkSfx(sound); - } - return sfx; -} - -uint32 -cAudioManager::GetShopperFemaleTalkSfx(int16 sound, int32 model) -{ - uint32 sfx; - static uint32 lastSfx = NO_SAMPLE; - - switch (sound) { - case SOUND_PED_CAR_JACKED: - GetPhrase(&sfx, &lastSfx, SFX_SHOPPER_VOICE_1_CARJACKED_1, 2); - break; - case SOUND_PED_ROBBED: - GetPhrase(&sfx, &lastSfx, SFX_SHOPPER_VOICE_1_MUGGED_1, 2); - break; - case SOUND_PED_EVADE: - GetPhrase(&sfx, &lastSfx, SFX_SHOPPER_VOICE_1_DODGE_1, 6); - break; - case SOUND_PED_CAR_COLLISION: - GetPhrase(&sfx, &lastSfx, SFX_SHOPPER_VOICE_1_DRIVER_ABUSE_1, 7); - break; - case SOUND_PED_CHAT_EVENT: - GetPhrase(&sfx, &lastSfx, SFX_SHOPPER_VOICE_1_SHOCKED_1, 4); - break; - case SOUND_PED_CHAT: - GetPhrase(&sfx, &lastSfx, SFX_SHOPPER_VOICE_1_CHAT_1, 7); - break; - default: - return GetGenericFemaleTalkSfx(sound); - } - -// TODO(MIAMI): just making this compile -// if (model == MI_SHOPPER2) { -// sfx += (SFX_SHOPPER_VOICE_2_DRIVER_ABUSE_1 - SFX_SHOPPER_VOICE_1_DRIVER_ABUSE_1); -// } else if (model == MI_SHOPPER3) { -// sfx += (SFX_SHOPPER_VOICE_3_DRIVER_ABUSE_1 - SFX_SHOPPER_VOICE_1_DRIVER_ABUSE_1); -// } - return sfx; -} - -uint32 -cAudioManager::GetStudentMaleTalkSfx(int16 sound) -{ - uint32 sfx; - static uint32 lastSfx = NO_SAMPLE; - - switch (sound) { - case SOUND_PED_HANDS_COWER: - GetPhrase(&sfx, &lastSfx, SFX_STUDENT_MALE_VOICE_1_GUN_PANIC_1, 2); - break; - case SOUND_PED_ROBBED: - GetPhrase(&sfx, &lastSfx, SFX_STUDENT_MALE_VOICE_1_MUGGED_1, 2); - break; - case SOUND_PED_ATTACK: - GetPhrase(&sfx, &lastSfx, SFX_STUDENT_MALE_VOICE_1_FIGHT_1, 4); - break; - case SOUND_PED_EVADE: - GetPhrase(&sfx, &lastSfx, SFX_STUDENT_MALE_VOICE_1_DODGE_1, 4); - break; - case SOUND_PED_CAR_COLLISION: - GetPhrase(&sfx, &lastSfx, SFX_STUDENT_MALE_VOICE_1_DRIVER_ABUSE_1, 4); - break; - case SOUND_PED_CHAT_EVENT: - GetPhrase(&sfx, &lastSfx, SFX_STUDENT_MALE_VOICE_1_SHOCKED_1, 3); - break; - case SOUND_PED_CHAT: - GetPhrase(&sfx, &lastSfx, SFX_STUDENT_MALE_VOICE_1_CHAT_1, 5); - break; - default: - return GetGenericMaleTalkSfx(sound); - } - return sfx; -} - -uint32 -cAudioManager::GetStudentFemaleTalkSfx(int16 sound) -{ - uint32 sfx; - static uint32 lastSfx = NO_SAMPLE; - - switch (sound) { - case SOUND_PED_HANDS_COWER: - GetPhrase(&sfx, &lastSfx, SFX_STUDENT_FEMALE_VOICE_1_GUN_PANIC_1, 4); - break; - case SOUND_PED_ROBBED: - GetPhrase(&sfx, &lastSfx, SFX_STUDENT_FEMALE_VOICE_1_MUGGED_1, 2); - break; - case SOUND_PED_ATTACK: - GetPhrase(&sfx, &lastSfx, SFX_STUDENT_FEMALE_VOICE_1_FIGHT_1, 4); - break; - case SOUND_PED_EVADE: - GetPhrase(&sfx, &lastSfx, SFX_STUDENT_FEMALE_VOICE_1_DODGE_1, 4); - break; - case SOUND_PED_CAR_COLLISION: - GetPhrase(&sfx, &lastSfx, SFX_STUDENT_FEMALE_VOICE_1_DRIVER_ABUSE_1, 4); - break; - case SOUND_PED_CHAT_EVENT: - GetPhrase(&sfx, &lastSfx, SFX_STUDENT_FEMALE_VOICE_1_SHOCKED_1, 2); - break; - case SOUND_PED_CHAT: - GetPhrase(&sfx, &lastSfx, SFX_STUDENT_FEMALE_VOICE_1_CHAT_1, 4); - break; - default: - return GetGenericFemaleTalkSfx(sound); - } - return sfx; -} - -uint32 -cAudioManager::GetCasualMaleOldTalkSfx(int16 sound) -{ - return GetGenericMaleTalkSfx(sound); -} - -uint32 -cAudioManager::GetSpecialCharacterTalkSfx(int32 modelIndex, int32 sound) -{ - char *modelName = CModelInfo::GetModelInfo(modelIndex)->GetName(); - if (!CGeneral::faststricmp(modelName, "eight") || !CGeneral::faststricmp(modelName, "eight2")) { - return GetEightTalkSfx(sound); - } - if (!CGeneral::faststricmp(modelName, "frankie")) { - return GetFrankieTalkSfx(sound); - } - if (!CGeneral::faststricmp(modelName, "misty")) { - return GetMistyTalkSfx(sound); - } - if (!CGeneral::faststricmp(modelName, "ojg") || !CGeneral::faststricmp(modelName, "ojg_p")) { - return GetOJGTalkSfx(sound); - } - if (!CGeneral::faststricmp(modelName, "cat")) { - return GetCatatalinaTalkSfx(sound); - } - if (!CGeneral::faststricmp(modelName, "bomber")) { - return GetBomberTalkSfx(sound); - } - if (!CGeneral::faststricmp(modelName, "s_guard")) { - return GetSecurityGuardTalkSfx(sound); - } - if (!CGeneral::faststricmp(modelName, "chunky")) { - return GetChunkyTalkSfx(sound); - } - if (!CGeneral::faststricmp(modelName, "asuka")) { - return GetGenericFemaleTalkSfx(sound); - } - if (!CGeneral::faststricmp(modelName, "maria")) { - return GetGenericFemaleTalkSfx(sound); - } - - return GetGenericMaleTalkSfx(sound); -} -uint32 -cAudioManager::GetEightTalkSfx(int16 sound) -{ - uint32 sfx; - static uint32 lastSfx = NO_SAMPLE; - - switch (sound) { - case SOUND_PED_HANDS_UP: - GetPhrase(&sfx, &lastSfx, SFX_8BALL_GUN_COOL_1, 2); - break; - case SOUND_PED_ROBBED: - GetPhrase(&sfx, &lastSfx, SFX_8BALL_MUGGED_1, 2); - break; - case SOUND_PED_ATTACK: - GetPhrase(&sfx, &lastSfx, SFX_8BALL_FIGHT_1, 6); - break; - case SOUND_PED_EVADE: - GetPhrase(&sfx, &lastSfx, SFX_8BALL_DODGE_1, 7); - break; - default: - return GetGenericMaleTalkSfx(sound); - } - return sfx; -} - -uint32 -cAudioManager::GetFrankieTalkSfx(int16 sound) -{ - uint32 sfx; - static uint32 lastSfx = NO_SAMPLE; - - switch (sound) { - case SOUND_PED_HANDS_UP: - GetPhrase(&sfx, &lastSfx, SFX_SALVATORE_GUN_COOL_1, 4); - break; - case SOUND_PED_ROBBED: - GetPhrase(&sfx, &lastSfx, SFX_SALVATORE_MUGGED_1, 2); - break; - case SOUND_PED_ATTACK: - GetPhrase(&sfx, &lastSfx, SFX_SALVATORE_FIGHT_1, 6); - break; - case SOUND_PED_EVADE: - GetPhrase(&sfx, &lastSfx, SFX_SALVATORE_DODGE_1, 3); - break; - default: - return GetGenericMaleTalkSfx(sound); - } - return sfx; -} - -uint32 -cAudioManager::GetMistyTalkSfx(int16 sound) -{ - uint32 sfx; - static uint32 lastSfx = NO_SAMPLE; - - switch (sound) { - case SOUND_PED_HANDS_UP: - GetPhrase(&sfx, &lastSfx, SFX_MISTY_GUN_COOL_1, 5); - break; - case SOUND_PED_ROBBED: - GetPhrase(&sfx, &lastSfx, SFX_MISTY_MUGGED_1, 2); - break; - case SOUND_PED_ATTACK: - GetPhrase(&sfx, &lastSfx, SFX_MISTY_FIGHT_1, 4); - break; - case SOUND_PED_EVADE: - GetPhrase(&sfx, &lastSfx, SFX_MISTY_DODGE_1, 5); - break; - case SOUND_PED_TAXI_CALL: - GetPhrase(&sfx, &lastSfx, SFX_MISTY_HERE_1, 4); - break; - default: - return GetGenericFemaleTalkSfx(sound); - break; - } - return sfx; -} - -uint32 -cAudioManager::GetOJGTalkSfx(int16 sound) -{ - return GetGenericMaleTalkSfx(sound); -} - -uint32 -cAudioManager::GetCatatalinaTalkSfx(int16 sound) -{ - return GetGenericFemaleTalkSfx(sound); -} - -uint32 -cAudioManager::GetBomberTalkSfx(int16 sound) -{ - uint32 sfx; - static uint32 lastSfx = NO_SAMPLE; - - if (sound != SOUND_PED_BOMBER) - return GetGenericMaleTalkSfx(sound); - - GetPhrase(&sfx, &lastSfx, SFX_BOMBERMAN_1, 7); - return sfx; -} - -uint32 -cAudioManager::GetSecurityGuardTalkSfx(int16 sound) -{ - uint32 sfx; - static uint32 lastSfx = NO_SAMPLE; - - switch (sound) { - case SOUND_PED_HANDS_UP: - GetPhrase(&sfx, &lastSfx, SFX_SECURITY_GUARD_VOICE_1_GUN_COOL_1, 2); - break; - case SOUND_PED_HANDS_COWER: - sfx = SFX_SECURITY_GUARD_VOICE_1_GUN_PANIC_1; - break; - case SOUND_PED_CAR_JACKED: - case SOUND_PED_CAR_COLLISION: - GetPhrase(&sfx, &lastSfx, SFX_SECURITY_GUARD_VOICE_1_DRIVER_ABUSE_1, 6); - break; - case SOUND_PED_ATTACK: - GetPhrase(&sfx, &lastSfx, SFX_SECURITY_GUARD_VOICE_1_FIGHT_1, 2); - break; - case SOUND_PED_FLEE_RUN: -#ifdef FIX_BUGS - sfx = SFX_SECURITY_GUARD_VOICE_1_RUN_FROM_FIGHT_1; -#else - GetPhrase(&sfx, &lastSfx, SFX_SECURITY_GUARD_VOICE_1_DRIVER_ABUSE_1, 12); -#endif - break; - default: - return GetGenericMaleTalkSfx(sound); - } - return sfx; -} - -uint32 -cAudioManager::GetChunkyTalkSfx(int16 sound) -{ - uint32 sfx; - static uint32 lastSfx = NO_SAMPLE; - - if (sound == SOUND_PED_DEATH) - return SFX_CHUNKY_DEATH; - - if (sound != SOUND_PED_FLEE_RUN) - return GetGenericMaleTalkSfx(sound); - - GetPhrase(&sfx, &lastSfx, SFX_CHUNKY_RUN_1, 5); - return sfx; -} - -uint32 -cAudioManager::GetGenericMaleTalkSfx(int16 sound) -{ - uint32 sfx; - static uint32 lastSfx = NO_SAMPLE; - - switch (sound) { - case SOUND_PED_DEATH: - GetPhrase(&sfx, &lastSfx, SFX_GENERIC_MALE_DEATH_1, 8); - break; - case SOUND_PED_BULLET_HIT: - case SOUND_PED_DEFEND: - GetPhrase(&sfx, &lastSfx, SFX_GENERIC_MALE_GRUNT_1, 15); - break; - case SOUND_PED_BURNING: - GetPhrase(&sfx, &lastSfx, SFX_GENERIC_MALE_FIRE_1, 8); - break; - case SOUND_PED_FLEE_SPRINT: - GetPhrase(&sfx, &lastSfx, SFX_GENERIC_MALE_PANIC_1, 6); - break; - default: - return NO_SAMPLE; - } - return sfx; -} - -uint32 -cAudioManager::GetGenericFemaleTalkSfx(int16 sound) -{ - uint32 sfx; - static uint32 lastSfx = NO_SAMPLE; - - switch (sound) { - case SOUND_PED_DEATH: - GetPhrase(&sfx, &lastSfx, SFX_GENERIC_FEMALE_DEATH_1, 10); - break; - case SOUND_PED_BULLET_HIT: - case SOUND_PED_DEFEND: - GetPhrase(&sfx, &lastSfx, SFX_GENERIC_FEMALE_GRUNT_1, 11); - break; - case SOUND_PED_BURNING: - GetPhrase(&sfx, &lastSfx, SFX_GENERIC_FEMALE_FIRE_1, 9); - break; - case SOUND_PED_FLEE_SPRINT: - GetPhrase(&sfx, &lastSfx, SFX_GENERIC_FEMALE_PANIC_1, 8); - break; - default: - return NO_SAMPLE; - } - return sfx; -} - -void -cAudioManager::GenerateIntegerRandomNumberTable() -{ - for (int32 i = 0; i < ARRAY_SIZE(m_anRandomTable); i++) { - m_anRandomTable[i] = rand(); - } -} - -char * -cAudioManager::Get3DProviderName(uint8 id) const -{ - if (!m_bIsInitialised) - return nil; - if (id >= SampleManager.GetNum3DProvidersAvailable()) - return nil; - return SampleManager.Get3DProviderName(id); -} - -uint8 -cAudioManager::GetCDAudioDriveLetter() const -{ - if (m_bIsInitialised) - return SampleManager.GetCDAudioDriveLetter(); - - return 0; -} - -int8 -cAudioManager::GetCurrent3DProviderIndex() const -{ - if (m_bIsInitialised) - return SampleManager.GetCurrent3DProviderIndex(); - - return -1; -} - -float -cAudioManager::GetDistanceSquared(const CVector &v) const -{ - const CVector &c = TheCamera.GetPosition(); - return sq(v.x - c.x) + sq(v.y - c.y) + sq((v.z - c.z) * 0.2f); -} - -int32 -cAudioManager::GetJumboTaxiFreq() const -{ - return (60.833f * m_sQueueSample.m_fDistance) + 22050; -} - -bool -cAudioManager::GetMissionAudioLoadingStatus() const -{ - if (m_bIsInitialised) - return m_sMissionAudio.m_nLoadingStatus; - - return true; -} - -uint8 -cAudioManager::GetNum3DProvidersAvailable() const -{ - if (m_bIsInitialised) - return SampleManager.GetNum3DProvidersAvailable(); - return 0; -} - -int32 -cAudioManager::GetPedCommentSfx(CPed *ped, int32 sound) -{ - if (ped->IsPlayer()) - return GetPlayerTalkSfx(sound); - - switch (ped->GetModelIndex()) { - case MI_COP: - return GetCopTalkSfx(sound); - case MI_SWAT: - return GetSwatTalkSfx(sound); - case MI_FBI: - return GetFBITalkSfx(sound); - case MI_ARMY: - return GetArmyTalkSfx(sound); - case MI_MEDIC: - return GetMedicTalkSfx(sound); - case MI_FIREMAN: - return GetFiremanTalkSfx(sound); - case MI_MALE01: - return GetNormalMaleTalkSfx(sound); - case MI_TAXI_D: - return GetTaxiDriverTalkSfx(sound); -// TODO(MIAMI): just making this compile -/* - case MI_PIMP: - return GetPimpTalkSfx(sound); - case MI_GANG01: - case MI_GANG02: - return GetMafiaTalkSfx(sound); - case MI_GANG03: - case MI_GANG04: - return GetTriadTalkSfx(sound); - case MI_GANG05: - case MI_GANG06: - return GetDiabloTalkSfx(sound); - case MI_GANG07: - case MI_GANG08: - return GetYakuzaTalkSfx(sound); - case MI_GANG09: - case MI_GANG10: - return GetYardieTalkSfx(sound); - case MI_GANG11: - case MI_GANG12: - return GetColumbianTalkSfx(sound); - case MI_GANG13: - case MI_GANG14: - return GetHoodTalkSfx(sound); - case MI_CRIMINAL01: - return GetBlackCriminalTalkSfx(sound); - case MI_CRIMINAL02: - return GetWhiteCriminalTalkSfx(sound); - case MI_SPECIAL01: - case MI_SPECIAL02: - case MI_SPECIAL03: - case MI_SPECIAL04: - return GetSpecialCharacterTalkSfx(ped->GetModelIndex(), sound); - case MI_MALE02: - return GetMaleNo2TalkSfx(sound); - case MI_MALE03: - case MI_P_MAN1: - case MI_P_MAN2: - return GetBlackProjectMaleTalkSfx(sound, ped->GetModelIndex()); - case MI_FATMALE01: - return GetWhiteFatMaleTalkSfx(sound); - case MI_FATMALE02: - return GetBlackFatMaleTalkSfx(sound); - case MI_FEMALE01: - return GetBlackCasualFemaleTalkSfx(sound); - case MI_FEMALE02: - case MI_CAS_WOM: - return GetWhiteCasualFemaleTalkSfx(sound); - case MI_FEMALE03: - return GetFemaleNo3TalkSfx(sound); - case MI_FATFEMALE01: - return GetBlackFatFemaleTalkSfx(sound); - case MI_FATFEMALE02: - return GetWhiteFatFemaleTalkSfx(sound); - case MI_PROSTITUTE: - return GetBlackFemaleProstituteTalkSfx(sound); - case MI_PROSTITUTE2: - return GetWhiteFemaleProstituteTalkSfx(sound); - case MI_P_WOM1: - return GetBlackProjectFemaleOldTalkSfx(sound); - case MI_P_WOM2: - return GetBlackProjectFemaleYoungTalkSfx(sound); - case MI_CT_MAN1: - return GetChinatownMaleOldTalkSfx(sound); - case MI_CT_MAN2: - return GetChinatownMaleYoungTalkSfx(sound); - case MI_CT_WOM1: - return GetChinatownFemaleOldTalkSfx(sound); - case MI_CT_WOM2: - return GetChinatownFemaleYoungTalkSfx(sound); - case MI_LI_MAN1: - case MI_LI_MAN2: - return GetLittleItalyMaleTalkSfx(sound); - case MI_LI_WOM1: - return GetLittleItalyFemaleOldTalkSfx(sound); - case MI_LI_WOM2: - return GetLittleItalyFemaleYoungTalkSfx(sound); - case MI_DOCKER1: - return GetWhiteDockerMaleTalkSfx(sound); - case MI_DOCKER2: - return GetBlackDockerMaleTalkSfx(sound); - case MI_SCUM_MAN: - return GetScumMaleTalkSfx(sound); - case MI_SCUM_WOM: - return GetScumFemaleTalkSfx(sound); - case MI_WORKER1: - return GetWhiteWorkerMaleTalkSfx(sound); - case MI_WORKER2: - return GetBlackWorkerMaleTalkSfx(sound); - case MI_B_MAN1: - case MI_B_MAN3: - return GetBusinessMaleYoungTalkSfx(sound, ped->GetModelIndex()); - case MI_B_MAN2: - return GetBusinessMaleOldTalkSfx(sound); - case MI_B_WOM1: - case MI_B_WOM2: - return GetWhiteBusinessFemaleTalkSfx(sound, ped->GetModelIndex()); - case MI_B_WOM3: - return GetBlackBusinessFemaleTalkSfx(sound); - case MI_MOD_MAN: - return GetSupermodelMaleTalkSfx(sound); - case MI_MOD_WOM: - return GetSupermodelFemaleTalkSfx(sound); - case MI_ST_MAN: - return GetStewardMaleTalkSfx(sound); - case MI_ST_WOM: - return GetStewardFemaleTalkSfx(sound); - case MI_FAN_MAN1: - case MI_FAN_MAN2: - return GetFanMaleTalkSfx(sound, ped->GetModelIndex()); - case MI_FAN_WOM: - return GetFanFemaleTalkSfx(sound); - case MI_HOS_MAN: - return GetHospitalMaleTalkSfx(sound); - case MI_HOS_WOM: - return GetHospitalFemaleTalkSfx(sound); - case MI_CONST1: - return GetWhiteConstructionWorkerTalkSfx(sound); - case MI_CONST2: - return GetBlackConstructionWorkerTalkSfx(sound); - case MI_SHOPPER1: - case MI_SHOPPER2: - case MI_SHOPPER3: - return GetShopperFemaleTalkSfx(sound, ped->GetModelIndex()); - case MI_STUD_MAN: - return GetStudentMaleTalkSfx(sound); - case MI_STUD_WOM: - return GetStudentFemaleTalkSfx(sound); - case MI_CAS_MAN: - return GetCasualMaleOldTalkSfx(sound); -*/ - default: - return GetGenericMaleTalkSfx(sound); - } -} - -void -cAudioManager::GetPhrase(uint32 *phrase, uint32 *prevPhrase, uint32 sample, uint32 maxOffset) const -{ - *phrase = sample + m_anRandomTable[m_sQueueSample.m_nEntityIndex & 3] % maxOffset; - - // check if the same sfx like last time, if yes, then try use next one, - // if exceeded range, then choose first available sample - if (*phrase == *prevPhrase && ++*phrase >= sample + maxOffset) - *phrase = sample; - *prevPhrase = *phrase; -} - -float -cAudioManager::GetVehicleDriveWheelSkidValue(uint8 wheel, CAutomobile *automobile, cTransmission *transmission, float velocityChange) -{ - tWheelState wheelState; - float relativeVelChange; - float gasPedalAudio = automobile->m_fGasPedalAudio; - float modificator; - float velChange; - float relativeVel; - - wheelState = automobile->m_aWheelState[wheel]; - if (wheelState == WHEEL_STATE_SPINNING && gasPedalAudio > 0.4f) { - relativeVelChange = (gasPedalAudio - 0.4f) * 1.25f; - - } else if (wheelState == WHEEL_STATE_SKIDDING) { - relativeVelChange = Min(1.0f, Abs(velocityChange) / transmission->fMaxVelocity); - } else if (wheelState == WHEEL_STATE_FIXED) { - modificator = 0.4f; - relativeVelChange = gasPedalAudio; - if (relativeVelChange > 0.4f) { - relativeVelChange = relativeVelChange - 0.4f; - modificator = 5.f / 3.f; - } - velChange = Abs(velocityChange); - if (relativeVelChange > 0.4f) - relativeVelChange = relativeVelChange * modificator; - if (velChange > 0.04f) { - relativeVel = Min(1.0f, velChange / transmission->fMaxVelocity); - } else { - relativeVel = 0.0f; - } - if (relativeVel >= relativeVelChange) - relativeVelChange = relativeVel; - } else { - relativeVelChange = 0.0f; - } - - return Max(relativeVelChange, Min(1.0f, Abs(automobile->m_vecTurnSpeed.z) * 20.0f)); -} - -float -cAudioManager::GetVehicleNonDriveWheelSkidValue(uint8 wheel, CAutomobile *automobile, cTransmission *transmission, float velocityChange) -{ - float relativeVelChange; - - if (automobile->m_aWheelState[wheel] == 2) { - relativeVelChange = Min(1.0f, Abs(velocityChange) / transmission->fMaxVelocity); - } else { - relativeVelChange = 0.0f; - } - - return Max(relativeVelChange, Min(1.0f, Abs(automobile->m_vecTurnSpeed.z) * 20.0f)); -} - -bool -cAudioManager::HasAirBrakes(int32 model) const -{ - return model == LINERUN || model == FIRETRUK || model == TRASH || model == BUS || model == COACH; -} - -void -cAudioManager::Initialise() -{ - if (!m_bIsInitialised) { - PreInitialiseGameSpecificSetup(); - m_bIsInitialised = SampleManager.Initialise(); - if (m_bIsInitialised) { - m_nActiveSamples = SampleManager.GetMaximumSupportedChannels(); - if (m_nActiveSamples <= 1) { - Terminate(); - } else { - --m_nActiveSamples; - PostInitialiseGameSpecificSetup(); - InitialisePoliceRadioZones(); - InitialisePoliceRadio(); - MusicManager.Initialise(); - } - } - } -} - -void -cAudioManager::InterrogateAudioEntities() -{ - for (int32 i = 0; i < m_nAudioEntitiesTotal; i++) { - ProcessEntity(m_anAudioEntityIndices[i]); - m_asAudioEntities[m_anAudioEntityIndices[i]].m_AudioEvents = 0; - } -} - -bool -cAudioManager::IsAudioInitialised() const -{ - return m_bIsInitialised; -} - -bool -cAudioManager::IsMissionAudioSampleFinished() -{ - if (m_bIsInitialised) - return m_sMissionAudio.m_nPlayStatus == PLAY_STATUS_FINISHED; - - static int32 cPretendFrame = 1; - - return (cPretendFrame++ & 63) == 0; -} - -bool -cAudioManager::IsMP3RadioChannelAvailable() const -{ - if (m_bIsInitialised) - return SampleManager.IsMP3RadioChannelAvailable(); - - return false; -} - -bool -cAudioManager::MissionScriptAudioUsesPoliceChannel(int32 soundMission) const -{ - switch (soundMission) { - case STREAMED_SOUND_MISSION_J6_D: - case STREAMED_SOUND_MISSION_T4_A: - case STREAMED_SOUND_MISSION_S1_H: - case STREAMED_SOUND_MISSION_S3_B: - case STREAMED_SOUND_MISSION_EL3_A: - case STREAMED_SOUND_MISSION_A3_A: - case STREAMED_SOUND_MISSION_A5_A: - case STREAMED_SOUND_MISSION_K1_A: - case STREAMED_SOUND_MISSION_R1_A: - case STREAMED_SOUND_MISSION_R5_A: - case STREAMED_SOUND_MISSION_LO2_A: - case STREAMED_SOUND_MISSION_LO6_A: - return true; - default: - return false; - } -} - -void -cAudioManager::PlayLoadedMissionAudio() -{ - if (m_bIsInitialised && m_sMissionAudio.m_nSampleIndex != NO_SAMPLE && m_sMissionAudio.m_nLoadingStatus == LOADING_STATUS_LOADED && - !m_sMissionAudio.m_nPlayStatus) { - m_sMissionAudio.m_bIsPlayed = true; - } -} - -void -cAudioManager::PlayOneShot(int32 index, int16 sound, float vol) -{ - static const uint8 OneShotPriority[] = {3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 5, 5, 5, 3, 5, 2, 2, 1, 1, 3, 1, 3, 3, 1, 1, 1, 4, 4, 3, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 6, 1, 1, 3, 2, 2, 2, 2, 0, 0, 6, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 3, 1, 1, 1, 9, - 2, 2, 0, 0, 0, 0, 3, 3, 5, 1, 1, 1, 1, 3, 4, 7, 6, 6, 6, 6, 1, 3, 4, 3, 4, 2, 1, 3, 5, 4, 6, 6, 1, 3, - 1, 1, 1, 0, 0, 0, 0, 0, 0, 3, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; - - if (m_bIsInitialised) { - if (index >= 0 && index < totalAudioEntitiesSlots) { - tAudioEntity &entity = m_asAudioEntities[index]; - if (entity.m_bIsUsed) { - if (sound < SOUND_TOTAL_SOUNDS) { - if (entity.m_nType == AUDIOTYPE_SCRIPTOBJECT) { - if (m_sAudioScriptObjectManager.m_nScriptObjectEntityTotal < ARRAY_SIZE(m_sAudioScriptObjectManager.m_anScriptObjectEntityIndices)) { - entity.m_awAudioEvent[0] = sound; - entity.m_AudioEvents = 1; - m_sAudioScriptObjectManager.m_anScriptObjectEntityIndices[m_sAudioScriptObjectManager.m_nScriptObjectEntityTotal++] = index; - } - } else { - int32 i = 0; - while (true) { - if (i >= entity.m_AudioEvents) { - if (entity.m_AudioEvents < ARRAY_SIZE(entity.m_awAudioEvent)) { - entity.m_awAudioEvent[i] = sound; - entity.m_afVolume[i] = vol; - ++entity.m_AudioEvents; - } - return; - } - if (OneShotPriority[entity.m_awAudioEvent[i]] > OneShotPriority[sound]) - break; - ++i; - } - if (i < NUM_AUDIOENTITY_EVENTS - 1) { - memmove(&entity.m_awAudioEvent[i + 1], &entity.m_awAudioEvent[i], (NUM_AUDIOENTITY_EVENTS - 1 - i) * NUM_AUDIOENTITY_EVENTS / 2); - memmove(&entity.m_afVolume[i + 1], &entity.m_afVolume[i], (NUM_AUDIOENTITY_EVENTS - 1 - i) * NUM_AUDIOENTITY_EVENTS); - } - entity.m_awAudioEvent[i] = sound; - entity.m_afVolume[i] = vol; - if (entity.m_AudioEvents < ARRAY_SIZE(entity.m_awAudioEvent)) - ++entity.m_AudioEvents; - } - } - } - } - } -} - -void -cAudioManager::PlayerJustGotInCar() const -{ - if (m_bIsInitialised) { - bPlayerJustEnteredCar = true; - } -} - -void -cAudioManager::PlayerJustLeftCar(void) const -{ - // UNUSED: This is a perfectly empty function. -} - -void -cAudioManager::PostInitialiseGameSpecificSetup() -{ - m_nFireAudioEntity = CreateEntity(AUDIOTYPE_FIRE, &gFireManager); - if (m_nFireAudioEntity >= 0) - SetEntityStatus(m_nFireAudioEntity, 1); - - m_nCollisionEntity = CreateEntity(AUDIOTYPE_COLLISION, (void *)1); - if (m_nCollisionEntity >= 0) - SetEntityStatus(m_nCollisionEntity, 1); - - m_nFrontEndEntity = CreateEntity(AUDIOTYPE_FRONTEND, (void *)1); - if (m_nFrontEndEntity >= 0) - SetEntityStatus(m_nFrontEndEntity, 1); - - m_nProjectileEntity = CreateEntity(AUDIOTYPE_PROJECTILE, (void *)1); - if (m_nProjectileEntity >= 0) - SetEntityStatus(m_nProjectileEntity, 1); - - m_nWaterCannonEntity = CreateEntity(AUDIOTYPE_WATERCANNON, (void *)1); - if (m_nWaterCannonEntity >= 0) - SetEntityStatus(m_nWaterCannonEntity, 1); - - m_nPoliceChannelEntity = CreateEntity(AUDIOTYPE_POLICERADIO, (void *)1); - if (m_nPoliceChannelEntity >= 0) - SetEntityStatus(m_nPoliceChannelEntity, 1); - - m_nBridgeEntity = CreateEntity(AUDIOTYPE_BRIDGE, (void *)1); - if (m_nBridgeEntity >= 0) - SetEntityStatus(m_nBridgeEntity, 1); - - m_sMissionAudio.m_nSampleIndex = NO_SAMPLE; - m_sMissionAudio.m_nLoadingStatus = LOADING_STATUS_NOT_LOADED; - m_sMissionAudio.m_nPlayStatus = PLAY_STATUS_STOPPED; - m_sMissionAudio.field_22 = 0; - m_sMissionAudio.m_bIsPlayed = false; - m_sMissionAudio.m_bPredefinedProperties = 1; - m_sMissionAudio.m_nMissionAudioCounter = 0; - ResetAudioLogicTimers(CTimer::GetTimeInMilliseconds()); -} - -void -cAudioManager::PostTerminateGameSpecificShutdown() -{ - ; -} - -void -cAudioManager::PreInitialiseGameSpecificSetup() const -{ - BankStartOffset[SAMPLEBANK_MAIN] = SFX_CAR_HORN_JEEP; - BankStartOffset[SAMPLEBANK_PED] = SFX_COP_VOICE_1_ARREST_1; -} - -struct MissionAudioData { - const char *m_pName; - int32 m_nId; -}; - -const MissionAudioData MissionAudioNameSfxAssoc[] = { - {"lib_a1", STREAMED_SOUND_MISSION_LIB_A1}, {"lib_a2", STREAMED_SOUND_MISSION_LIB_A2}, {"lib_a", STREAMED_SOUND_MISSION_LIB_A}, - {"lib_b", STREAMED_SOUND_MISSION_LIB_B}, {"lib_c", STREAMED_SOUND_MISSION_LIB_C}, {"lib_d", STREAMED_SOUND_MISSION_LIB_D}, - {"l2_a", STREAMED_SOUND_MISSION_L2_A}, {"j4t_1", STREAMED_SOUND_MISSION_J4T_1}, {"j4t_2", STREAMED_SOUND_MISSION_J4T_2}, - {"j4t_3", STREAMED_SOUND_MISSION_J4T_3}, {"j4t_4", STREAMED_SOUND_MISSION_J4T_4}, {"j4_a", STREAMED_SOUND_MISSION_J4_A}, - {"j4_b", STREAMED_SOUND_MISSION_J4_B}, {"j4_c", STREAMED_SOUND_MISSION_J4_C}, {"j4_d", STREAMED_SOUND_MISSION_J4_D}, - {"j4_e", STREAMED_SOUND_MISSION_J4_E}, {"j4_f", STREAMED_SOUND_MISSION_J4_F}, {"j6_1", STREAMED_SOUND_MISSION_J6_1}, - {"j6_a", STREAMED_SOUND_MISSION_J6_A}, {"j6_b", STREAMED_SOUND_MISSION_J6_B}, {"j6_c", STREAMED_SOUND_MISSION_J6_C}, - {"j6_d", STREAMED_SOUND_MISSION_J6_D}, {"t4_a", STREAMED_SOUND_MISSION_T4_A}, {"s1_a", STREAMED_SOUND_MISSION_S1_A}, - {"s1_a1", STREAMED_SOUND_MISSION_S1_A1}, {"s1_b", STREAMED_SOUND_MISSION_S1_B}, {"s1_c", STREAMED_SOUND_MISSION_S1_C}, - {"s1_c1", STREAMED_SOUND_MISSION_S1_C1}, {"s1_d", STREAMED_SOUND_MISSION_S1_D}, {"s1_e", STREAMED_SOUND_MISSION_S1_E}, - {"s1_f", STREAMED_SOUND_MISSION_S1_F}, {"s1_g", STREAMED_SOUND_MISSION_S1_G}, {"s1_h", STREAMED_SOUND_MISSION_S1_H}, - {"s1_i", STREAMED_SOUND_MISSION_S1_I}, {"s1_j", STREAMED_SOUND_MISSION_S1_J}, {"s1_k", STREAMED_SOUND_MISSION_S1_K}, - {"s1_l", STREAMED_SOUND_MISSION_S1_L}, {"s3_a", STREAMED_SOUND_MISSION_S3_A}, {"s3_b", STREAMED_SOUND_MISSION_S3_B}, - {"el3_a", STREAMED_SOUND_MISSION_EL3_A}, {"mf1_a", STREAMED_SOUND_MISSION_MF1_A}, {"mf2_a", STREAMED_SOUND_MISSION_MF2_A}, - {"mf3_a", STREAMED_SOUND_MISSION_MF3_A}, {"mf3_b", STREAMED_SOUND_MISSION_MF3_B}, {"mf3_b1", STREAMED_SOUND_MISSION_MF3_B1}, - {"mf3_c", STREAMED_SOUND_MISSION_MF3_C}, {"mf4_a", STREAMED_SOUND_MISSION_MF4_A}, {"mf4_b", STREAMED_SOUND_MISSION_MF4_B}, - {"mf4_c", STREAMED_SOUND_MISSION_MF4_C}, {"a1_a", STREAMED_SOUND_MISSION_A1_A}, {"a3_a", STREAMED_SOUND_MISSION_A3_A}, - {"a5_a", STREAMED_SOUND_MISSION_A5_A}, {"a4_a", STREAMED_SOUND_MISSION_A4_A}, {"a4_b", STREAMED_SOUND_MISSION_A4_B}, - {"a4_c", STREAMED_SOUND_MISSION_A4_C}, {"a4_d", STREAMED_SOUND_MISSION_A4_D}, {"k1_a", STREAMED_SOUND_MISSION_K1_A}, - {"k3_a", STREAMED_SOUND_MISSION_K3_A}, {"r1_a", STREAMED_SOUND_MISSION_R1_A}, {"r2_a", STREAMED_SOUND_MISSION_R2_A}, - {"r2_b", STREAMED_SOUND_MISSION_R2_B}, {"r2_c", STREAMED_SOUND_MISSION_R2_C}, {"r2_d", STREAMED_SOUND_MISSION_R2_D}, - {"r2_e", STREAMED_SOUND_MISSION_R2_E}, {"r2_f", STREAMED_SOUND_MISSION_R2_F}, {"r2_g", STREAMED_SOUND_MISSION_R2_G}, - {"r2_h", STREAMED_SOUND_MISSION_R2_H}, {"r5_a", STREAMED_SOUND_MISSION_R5_A}, {"r6_a", STREAMED_SOUND_MISSION_R6_A}, - {"r6_a1", STREAMED_SOUND_MISSION_R6_A1}, {"r6_b", STREAMED_SOUND_MISSION_R6_B}, {"lo2_a", STREAMED_SOUND_MISSION_LO2_A}, - {"lo6_a", STREAMED_SOUND_MISSION_LO6_A}, {"yd2_a", STREAMED_SOUND_MISSION_YD2_A}, {"yd2_b", STREAMED_SOUND_MISSION_YD2_B}, - {"yd2_c", STREAMED_SOUND_MISSION_YD2_C}, {"yd2_c1", STREAMED_SOUND_MISSION_YD2_C1}, {"yd2_d", STREAMED_SOUND_MISSION_YD2_D}, - {"yd2_e", STREAMED_SOUND_MISSION_YD2_E}, {"yd2_f", STREAMED_SOUND_MISSION_YD2_F}, {"yd2_g", STREAMED_SOUND_MISSION_YD2_G}, - {"yd2_h", STREAMED_SOUND_MISSION_YD2_H}, {"yd2_ass", STREAMED_SOUND_MISSION_YD2_ASS}, {"yd2_ok", STREAMED_SOUND_MISSION_YD2_OK}, - {"h5_a", STREAMED_SOUND_MISSION_H5_A}, {"h5_b", STREAMED_SOUND_MISSION_H5_B}, {"h5_c", STREAMED_SOUND_MISSION_H5_C}, - {"ammu_a", STREAMED_SOUND_MISSION_AMMU_A}, {"ammu_b", STREAMED_SOUND_MISSION_AMMU_B}, {"ammu_c", STREAMED_SOUND_MISSION_AMMU_C}, - {"door_1", STREAMED_SOUND_MISSION_DOOR_1}, {"door_2", STREAMED_SOUND_MISSION_DOOR_2}, {"door_3", STREAMED_SOUND_MISSION_DOOR_3}, - {"door_4", STREAMED_SOUND_MISSION_DOOR_4}, {"door_5", STREAMED_SOUND_MISSION_DOOR_5}, {"door_6", STREAMED_SOUND_MISSION_DOOR_6}, - {"t3_a", STREAMED_SOUND_MISSION_T3_A}, {"t3_b", STREAMED_SOUND_MISSION_T3_B}, {"t3_c", STREAMED_SOUND_MISSION_T3_C}, - {"k1_b", STREAMED_SOUND_MISSION_K1_B}, {"c_1", STREAMED_SOUND_MISSION_CAT1}}; - -int32 -FindMissionAudioSfx(const char *name) -{ - for (uint32 i = 0; i < ARRAY_SIZE(MissionAudioNameSfxAssoc); ++i) { - if (!CGeneral::faststricmp(MissionAudioNameSfxAssoc[i].m_pName, name)) - return MissionAudioNameSfxAssoc[i].m_nId; - } - debug("Can't find mission audio %s", name); - return NO_SAMPLE; -} - -void -cAudioManager::PreloadMissionAudio(const char *name) -{ - if (m_bIsInitialised) { - int32 missionAudioSfx = FindMissionAudioSfx(name); - if (missionAudioSfx != NO_SAMPLE) { - m_sMissionAudio.m_nSampleIndex = missionAudioSfx; - m_sMissionAudio.m_nLoadingStatus = LOADING_STATUS_NOT_LOADED; - m_sMissionAudio.m_nPlayStatus = PLAY_STATUS_STOPPED; - m_sMissionAudio.field_22 = 0; - m_sMissionAudio.m_nMissionAudioCounter = m_nTimeSpent * SampleManager.GetStreamedFileLength(missionAudioSfx) / 1000; - m_sMissionAudio.m_nMissionAudioCounter *= 4; - m_sMissionAudio.m_bIsPlayed = false; - m_sMissionAudio.m_bPredefinedProperties = 1; - g_bMissionAudioLoadFailed = false; - } - } -} -void -cAudioManager::PreTerminateGameSpecificShutdown() -{ - if (m_nBridgeEntity >= 0) { - DestroyEntity(m_nBridgeEntity); - m_nBridgeEntity = AEHANDLE_NONE; - } - if (m_nPoliceChannelEntity >= 0) { - DestroyEntity(m_nPoliceChannelEntity); - m_nPoliceChannelEntity = AEHANDLE_NONE; - } - if (m_nWaterCannonEntity >= 0) { - DestroyEntity(m_nWaterCannonEntity); - m_nWaterCannonEntity = AEHANDLE_NONE; - } - if (m_nFireAudioEntity >= 0) { - DestroyEntity(m_nFireAudioEntity); - m_nFireAudioEntity = AEHANDLE_NONE; - } - if (m_nCollisionEntity >= 0) { - DestroyEntity(m_nCollisionEntity); - m_nCollisionEntity = AEHANDLE_NONE; - } - if (m_nFrontEndEntity >= 0) { - DestroyEntity(m_nFrontEndEntity); - m_nFrontEndEntity = AEHANDLE_NONE; - } - if (m_nProjectileEntity >= 0) { - DestroyEntity(m_nProjectileEntity); - m_nProjectileEntity = AEHANDLE_NONE; - } -} - void cAudioManager::ProcessActiveQueues() { @@ -3737,6130 +895,57 @@ cAudioManager::ProcessActiveQueues() } } -bool -cAudioManager::ProcessAirBrakes(cVehicleParams *params) -{ - CAutomobile *automobile; - uint8 rand; - - if (params->m_fDistance > 900.0f) - return false; - automobile = (CAutomobile *)params->m_pVehicle; - if (!automobile->bEngineOn) - return true; - - if ((automobile->m_fVelocityChangeForAudio < 0.025f || params->m_fVelocityChange >= 0.025f) && - (automobile->m_fVelocityChangeForAudio > -0.025f || params->m_fVelocityChange <= 0.025f)) - return true; - - CalculateDistance(params->m_bDistanceCalculated, params->m_fDistance); - rand = m_anRandomTable[0] % 10 + 70; - m_sQueueSample.m_nVolume = ComputeVolume(rand, 30.0f, m_sQueueSample.m_fDistance); - if (m_sQueueSample.m_nVolume) { - m_sQueueSample.m_nCounter = 13; - m_sQueueSample.m_nSampleIndex = SFX_AIR_BRAKES; - m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_AIR_BRAKES); - m_sQueueSample.m_nFrequency += RandomDisplacement(m_sQueueSample.m_nFrequency / 16); - m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; - m_sQueueSample.m_bIs2D = false; - m_sQueueSample.m_nReleasingVolumeModificator = 10; - m_sQueueSample.m_nLoopCount = 1; - m_sQueueSample.m_nEmittingVolume = rand; - m_sQueueSample.m_nLoopStart = 0; - m_sQueueSample.m_nLoopEnd = -1; - m_sQueueSample.m_fSpeedMultiplier = 0.0f; - m_sQueueSample.m_fSoundIntensity = 30.0f; - m_sQueueSample.m_bReleasingSoundFlag = true; - m_sQueueSample.m_bReverbFlag = true; - m_sQueueSample.m_bRequireReflection = false; - AddSampleToRequestedQueue(); - } - - return true; -} - -void -cAudioManager::ProcessAirportScriptObject(uint8 sound) -{ - static uint8 counter = 0; - - uint32 time = CTimer::GetTimeInMilliseconds(); - if (time > gAirportNextTime) { - switch (sound) { - case SCRIPT_SOUND_AIRPORT_LOOP_S: - m_sQueueSample.m_fSoundIntensity = scriptObjectIntensityS; - break; - case SCRIPT_SOUND_AIRPORT_LOOP_L: - m_sQueueSample.m_fSoundIntensity = scriptObjectIntensityL; - break; - default: - return; - } - float distSquared = GetDistanceSquared(m_sQueueSample.m_vecPos); - if (distSquared < SQR(m_sQueueSample.m_fSoundIntensity)) { - m_sQueueSample.m_fDistance = Sqrt(distSquared); - m_sQueueSample.m_nVolume = ComputeVolume(110, m_sQueueSample.m_fSoundIntensity, m_sQueueSample.m_fDistance); - if (m_sQueueSample.m_nVolume) { - m_sQueueSample.m_nSampleIndex = (m_anRandomTable[1] & 3) + SFX_AIRPORT_ANNOUNCEMENT_1; - m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; - m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(m_sQueueSample.m_nSampleIndex); - m_sQueueSample.m_nCounter = counter++; - m_sQueueSample.m_bIs2D = false; - m_sQueueSample.m_nLoopCount = 1; - m_sQueueSample.m_bReleasingSoundFlag = true; - m_sQueueSample.m_nReleasingVolumeModificator = 3; - m_sQueueSample.m_fSpeedMultiplier = 2.0f; - m_sQueueSample.m_nEmittingVolume = 110; - m_sQueueSample.m_nLoopStart = 0; - m_sQueueSample.m_nLoopEnd = -1; - m_sQueueSample.m_bReverbFlag = true; - m_sQueueSample.m_bRequireReflection = false; - AddSampleToRequestedQueue(); - gAirportNextTime = time + 10000 + m_anRandomTable[3] % 20000; - } - } - } -} - -bool -cAudioManager::ProcessBoatEngine(cVehicleParams *params) -{ - CBoat *boat; - float padRelativeAccerate; - float gasPedal; - int32 padAccelerate; - uint8 emittingVol; - float oneShotVol; - - static uint16 LastAccel = 0; - static uint8 LastVol = 0; - - static const int intensity = 50; - - if (params->m_fDistance < SQR(intensity)) { - boat = (CBoat *)params->m_pVehicle; - if (params->m_nIndex == REEFER) { - CalculateDistance(params->m_bDistanceCalculated, params->m_fDistance); - m_sQueueSample.m_nVolume = ComputeVolume(80, 50.f, m_sQueueSample.m_fDistance); - if (m_sQueueSample.m_nVolume) { - m_sQueueSample.m_nCounter = 39; - m_sQueueSample.m_nSampleIndex = SFX_FISHING_BOAT_IDLE; - m_sQueueSample.m_nFrequency = 10386; - m_sQueueSample.m_nFrequency += (m_sQueueSample.m_nEntityIndex * 65536) % 1000; - m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; - m_sQueueSample.m_bIs2D = false; - m_sQueueSample.m_nReleasingVolumeModificator = 3; - m_sQueueSample.m_nLoopCount = 0; - m_sQueueSample.m_nEmittingVolume = 80; - m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex); - m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex); - m_sQueueSample.m_fSpeedMultiplier = 2.0f; - m_sQueueSample.m_fSoundIntensity = intensity; - m_sQueueSample.m_bReleasingSoundFlag = false; - m_sQueueSample.m_nReleasingVolumeDivider = 7; - m_sQueueSample.m_bReverbFlag = true; - m_sQueueSample.m_bRequireReflection = false; - AddSampleToRequestedQueue(); - } - if (FindPlayerVehicle() == params->m_pVehicle) { - if (Pads[0].GetAccelerate() <= Pads[0].GetBrake()) - padAccelerate = Pads[0].GetBrake(); - else - padAccelerate = Pads[0].GetAccelerate(); - padRelativeAccerate = padAccelerate / 255; - emittingVol = (100.f * padRelativeAccerate) + 15; - m_sQueueSample.m_nFrequency = (3000.f * padRelativeAccerate) + 6000; - if (!boat->m_bIsAnchored) - m_sQueueSample.m_nFrequency = 11 * m_sQueueSample.m_nFrequency / 10; - } else { - gasPedal = Abs(boat->m_fGasPedal); - if (gasPedal > 0.0f) { - m_sQueueSample.m_nFrequency = 6000; - emittingVol = 15; - } else { - emittingVol = (100.f * gasPedal) + 15; - m_sQueueSample.m_nFrequency = (3000.f * gasPedal) + 6000; - if (!boat->m_bIsAnchored) - m_sQueueSample.m_nFrequency = 11 * m_sQueueSample.m_nFrequency / 10; - } - } - m_sQueueSample.m_nVolume = ComputeVolume(emittingVol, 50.f, m_sQueueSample.m_fDistance); - if (!m_sQueueSample.m_nVolume) - return true; - m_sQueueSample.m_nCounter = 40; - m_sQueueSample.m_nSampleIndex = SFX_POLICE_BOAT_ACCEL; - m_sQueueSample.m_nFrequency += (m_sQueueSample.m_nEntityIndex * 65536) % 1000; - m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; - m_sQueueSample.m_bIs2D = false; - m_sQueueSample.m_nReleasingVolumeModificator = 3; - m_sQueueSample.m_nLoopCount = 0; - m_sQueueSample.m_nEmittingVolume = emittingVol; - m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex); - m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex); - m_sQueueSample.m_fSpeedMultiplier = 2.0f; - m_sQueueSample.m_fSoundIntensity = intensity; - m_sQueueSample.m_bReleasingSoundFlag = false; - m_sQueueSample.m_nReleasingVolumeDivider = 7; - m_sQueueSample.m_bReverbFlag = true; - m_sQueueSample.m_bRequireReflection = false; - } else { - if (FindPlayerVehicle() == params->m_pVehicle) { - if (Pads[0].GetAccelerate() <= Pads[0].GetBrake()) - padAccelerate = Pads[0].GetBrake(); - else - padAccelerate = Pads[0].GetAccelerate(); - if (padAccelerate <= 20) { - emittingVol = 45 - 45 * padAccelerate / 40; - m_sQueueSample.m_nFrequency = 100 * padAccelerate + 11025; - m_sQueueSample.m_nCounter = 39; - m_sQueueSample.m_nSampleIndex = SFX_POLICE_BOAT_IDLE; - if (LastAccel > 20) { - oneShotVol = LastVol; - PlayOneShot(m_sQueueSample.m_nEntityIndex, SOUND_17, oneShotVol); - } - } else { - emittingVol = 105 * padAccelerate / 255 + 15; - m_sQueueSample.m_nFrequency = 4000 * padAccelerate / 255 + 8000; - if (!boat->m_bIsAnchored) - m_sQueueSample.m_nFrequency = 11 * m_sQueueSample.m_nFrequency / 10; - m_sQueueSample.m_nCounter = 40; - m_sQueueSample.m_nSampleIndex = SFX_POLICE_BOAT_ACCEL; - } - LastVol = emittingVol; - LastAccel = padAccelerate; - } else { - gasPedal = Abs(boat->m_fGasPedal); - if (gasPedal > 0.0f) { - m_sQueueSample.m_nFrequency = 11025; - emittingVol = 45; - m_sQueueSample.m_nCounter = 39; - m_sQueueSample.m_nSampleIndex = SFX_POLICE_BOAT_IDLE; - } else { - emittingVol = (105.f * gasPedal) + 15; - m_sQueueSample.m_nFrequency = (4000.f * gasPedal) + 8000; - if (!boat->m_bIsAnchored) - m_sQueueSample.m_nFrequency = 11 * m_sQueueSample.m_nFrequency / 10; - m_sQueueSample.m_nCounter = 40; - m_sQueueSample.m_nSampleIndex = SFX_POLICE_BOAT_ACCEL; - } - } - CalculateDistance(params->m_bDistanceCalculated, params->m_fDistance); - m_sQueueSample.m_nVolume = ComputeVolume(emittingVol, 50.f, m_sQueueSample.m_fDistance); - if (!m_sQueueSample.m_nVolume) - return true; - m_sQueueSample.m_nFrequency += (m_sQueueSample.m_nEntityIndex * 65536) % 1000; - m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; - m_sQueueSample.m_bIs2D = false; - m_sQueueSample.m_nReleasingVolumeModificator = 3; - m_sQueueSample.m_nLoopCount = 0; - m_sQueueSample.m_nEmittingVolume = emittingVol; - m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex); - m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex); - m_sQueueSample.m_fSpeedMultiplier = 2.0f; - m_sQueueSample.m_fSoundIntensity = intensity; - m_sQueueSample.m_bReleasingSoundFlag = false; - m_sQueueSample.m_nReleasingVolumeDivider = 7; - m_sQueueSample.m_bReverbFlag = true; - m_sQueueSample.m_bRequireReflection = false; - } - AddSampleToRequestedQueue(); - return true; - } - return false; -} - -bool -cAudioManager::ProcessBoatMovingOverWater(cVehicleParams *params) -{ - float velocityChange; - int32 vol; - float multiplier; - - if (params->m_fDistance > 2500.f) - return false; - - velocityChange = Abs(params->m_fVelocityChange); - if (velocityChange <= 0.0005f && params->m_pVehicle->GetPosition().y) - return true; - - velocityChange = Min(0.75f, velocityChange); - multiplier = (velocityChange - 0.0005f) * 1.3342f; - CalculateDistance(params->m_bDistanceCalculated, params->m_fDistance); - vol = (30.f * multiplier); - m_sQueueSample.m_nVolume = ComputeVolume(vol, 50.f, m_sQueueSample.m_fDistance); - if (m_sQueueSample.m_nVolume) { - m_sQueueSample.m_nCounter = 38; - m_sQueueSample.m_nSampleIndex = SFX_BOAT_WATER_LOOP; - m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; - m_sQueueSample.m_bIs2D = false; - m_sQueueSample.m_nReleasingVolumeModificator = 3; - m_sQueueSample.m_nFrequency = (6050.f * multiplier) + 16000; - m_sQueueSample.m_nLoopCount = 0; - m_sQueueSample.m_nEmittingVolume = vol; - m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex); - m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex); - m_sQueueSample.m_fSpeedMultiplier = 2.0f; - m_sQueueSample.m_fSoundIntensity = 50.0f; - m_sQueueSample.m_bReleasingSoundFlag = false; - m_sQueueSample.m_nReleasingVolumeDivider = 3; - m_sQueueSample.m_bReverbFlag = true; - m_sQueueSample.m_bRequireReflection = false; - AddSampleToRequestedQueue(); - } - - return true; -} - -void -cAudioManager::ProcessBridge() -{ - float dist; - bool distCalculated = false; - - if (CBridge::pLiftRoad) { - m_sQueueSample.m_vecPos = CBridge::pLiftRoad->GetPosition(); - dist = GetDistanceSquared(m_sQueueSample.m_vecPos); - if (dist < 202500.0f) { - CalculateDistance(distCalculated, dist); - switch (CBridge::State) { - case STATE_BRIDGE_LOCKED: - case STATE_LIFT_PART_IS_UP: - case STATE_LIFT_PART_ABOUT_TO_MOVE_UP: - ProcessBridgeWarning(); - break; - case STATE_LIFT_PART_MOVING_DOWN: - case STATE_LIFT_PART_MOVING_UP: - ProcessBridgeWarning(); - ProcessBridgeMotor(); - break; - default: - break; - } - ProcessBridgeOneShots(); - } - } -} - -void -cAudioManager::ProcessBridgeMotor() -{ - if (m_sQueueSample.m_fDistance < bridgeIntensity) { - m_sQueueSample.m_nVolume = ComputeVolume(maxVolume, bridgeIntensity, m_sQueueSample.m_fDistance); - if (m_sQueueSample.m_nVolume) { - m_sQueueSample.m_nCounter = 1; - m_sQueueSample.m_nSampleIndex = SFX_FISHING_BOAT_IDLE; // todo check sfx name - m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; - m_sQueueSample.m_bIs2D = false; - m_sQueueSample.m_nReleasingVolumeModificator = 1; - m_sQueueSample.m_nFrequency = 5500; - m_sQueueSample.m_nLoopCount = 0; - m_sQueueSample.m_nEmittingVolume = maxVolume; - m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex); - m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex); - m_sQueueSample.m_fSpeedMultiplier = 2.0f; - m_sQueueSample.m_fSoundIntensity = bridgeIntensity; - m_sQueueSample.m_bReleasingSoundFlag = false; - m_sQueueSample.m_nReleasingVolumeDivider = 3; - m_sQueueSample.m_bReverbFlag = false; - AddSampleToRequestedQueue(); - } - } -} - -void -cAudioManager::ProcessBridgeOneShots() -{ - if (CBridge::State == STATE_LIFT_PART_IS_UP && CBridge::OldState == STATE_LIFT_PART_MOVING_UP) { - m_sQueueSample.m_nSampleIndex = SFX_COL_CONTAINER_1; - } else { - if (CBridge::State == STATE_LIFT_PART_IS_DOWN && CBridge::OldState == STATE_LIFT_PART_MOVING_DOWN) { - m_sQueueSample.m_nSampleIndex = SFX_COL_CONTAINER_1; - } else { - if (CBridge::State == STATE_LIFT_PART_MOVING_UP && CBridge::OldState == STATE_LIFT_PART_ABOUT_TO_MOVE_UP) { - m_sQueueSample.m_nSampleIndex = SFX_COL_CONTAINER_1; - } else { - if (CBridge::State == STATE_LIFT_PART_MOVING_DOWN && CBridge::OldState == STATE_LIFT_PART_IS_UP) { - m_sQueueSample.m_nSampleIndex = SFX_COL_CONTAINER_1; - } else - return; - } - } - } - if (m_sQueueSample.m_fDistance < bridgeIntensity) { - m_sQueueSample.m_nVolume = ComputeVolume(maxVolume, bridgeIntensity, m_sQueueSample.m_fDistance); - if (m_sQueueSample.m_nVolume) { - m_sQueueSample.m_nCounter = 2; - m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; - m_sQueueSample.m_bIs2D = false; - m_sQueueSample.m_nReleasingVolumeModificator = 1; - m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(m_sQueueSample.m_nSampleIndex); - m_sQueueSample.m_nLoopCount = 1; - m_sQueueSample.m_nEmittingVolume = maxVolume; - m_sQueueSample.m_nLoopStart = 0; - m_sQueueSample.m_nLoopEnd = -1; - m_sQueueSample.m_fSpeedMultiplier = 2.0f; - m_sQueueSample.m_fSoundIntensity = bridgeIntensity; - m_sQueueSample.m_bReleasingSoundFlag = true; - m_sQueueSample.m_bReverbFlag = false; - m_sQueueSample.m_bRequireReflection = false; - AddSampleToRequestedQueue(); - } - } -} - -void -cAudioManager::ProcessBridgeWarning() -{ - if (CStats::CommercialPassed && m_sQueueSample.m_fDistance < 450.f) { - m_sQueueSample.m_nVolume = ComputeVolume(100, 450.f, m_sQueueSample.m_fDistance); - if (m_sQueueSample.m_nVolume) { - m_sQueueSample.m_nCounter = 0; - m_sQueueSample.m_nSampleIndex = SFX_BRIDGE_OPEN_WARNING; - m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; - m_sQueueSample.m_bIs2D = false; - m_sQueueSample.m_nReleasingVolumeModificator = 1; - m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_BRIDGE_OPEN_WARNING); - m_sQueueSample.m_nLoopCount = 0; - m_sQueueSample.m_nEmittingVolume = 100; - m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex); - m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex); - m_sQueueSample.m_fSpeedMultiplier = 2.0f; - m_sQueueSample.m_fSoundIntensity = 450.0f; - m_sQueueSample.m_bReleasingSoundFlag = false; - m_sQueueSample.m_nReleasingVolumeDivider = 8; - m_sQueueSample.m_bReverbFlag = false; - m_sQueueSample.m_bRequireReflection = false; - AddSampleToRequestedQueue(); - } - } -} - -bool -cAudioManager::ProcessCarBombTick(cVehicleParams *params) -{ - CAutomobile *automobile; - - if (params->m_fDistance >= SQR(40.f)) - return false; - automobile = (CAutomobile *)params->m_pVehicle; - if (automobile->bEngineOn && automobile->m_bombType == CARBOMB_TIMEDACTIVE) { - CalculateDistance(params->m_bDistanceCalculated, params->m_fDistance); - m_sQueueSample.m_nVolume = ComputeVolume(60, 40.f, m_sQueueSample.m_fDistance); - if (m_sQueueSample.m_nVolume) { - m_sQueueSample.m_nCounter = 35; - m_sQueueSample.m_nSampleIndex = SFX_COUNTDOWN; - m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; - m_sQueueSample.m_bIs2D = false; - m_sQueueSample.m_nReleasingVolumeModificator = 0; - m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_COUNTDOWN); - m_sQueueSample.m_nLoopCount = 0; - m_sQueueSample.m_nEmittingVolume = 60; - m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex); - m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex); - m_sQueueSample.m_fSpeedMultiplier = 2.0f; - m_sQueueSample.m_fSoundIntensity = 40.0f; - m_sQueueSample.m_bReleasingSoundFlag = false; - m_sQueueSample.m_nReleasingVolumeDivider = 3; - m_sQueueSample.m_bReverbFlag = true; - m_sQueueSample.m_bRequireReflection = false; - AddSampleToRequestedQueue(); - } - } - return true; -} - -void -cAudioManager::ProcessCesna(cVehicleParams *params) -{ - static uint8 nAccel = 0; - - //((CAutomobile *)params->m_pVehicle)->Damage.GetEngineStatus(); - - if (FindPlayerVehicle() == params->m_pVehicle) { - if (params->m_nIndex == DODO) { - if (Pads[0].GetAccelerate() <= 0) { - if (nAccel) - --nAccel; - } else if (nAccel < 60) { - ++nAccel; - } - AddPlayerCarSample(85 * (60 - nAccel) / 60 + 20, 8500 * nAccel / 60 + 17000, SFX_CESNA_IDLE, 0, 52, 1); - AddPlayerCarSample(85 * nAccel / 60 + 20, 8500 * nAccel / 60 + 17000, SFX_CESNA_REV, 0, 2, 1); - } - } else if (params->m_nIndex == DODO) { - AddPlayerCarSample(105, 17000, SFX_CESNA_IDLE, 0, 52, 1); - } else if (params->m_fDistance < 40000.f) { - CalculateDistance(params->m_bDistanceCalculated, params->m_fDistance); - m_sQueueSample.m_nVolume = ComputeVolume(80, 200.f, m_sQueueSample.m_fDistance); - if (m_sQueueSample.m_nVolume) { - m_sQueueSample.m_nCounter = 52; - m_sQueueSample.m_nSampleIndex = SFX_CESNA_IDLE; - m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; - m_sQueueSample.m_bIs2D = false; - m_sQueueSample.m_nReleasingVolumeModificator = 0; - m_sQueueSample.m_nFrequency = 12500; - m_sQueueSample.m_nLoopCount = 0; - m_sQueueSample.m_nReleasingVolumeDivider = 8; - m_sQueueSample.m_nEmittingVolume = 80; - m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex); - m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex); - m_sQueueSample.m_fSpeedMultiplier = 8.0f; - m_sQueueSample.m_fSoundIntensity = 200.0f; - m_sQueueSample.m_bReleasingSoundFlag = false; - m_sQueueSample.m_bReverbFlag = true; - m_sQueueSample.m_bRequireReflection = false; - AddSampleToRequestedQueue(); - } - if (params->m_fDistance < 8100.f) { - m_sQueueSample.m_nVolume = ComputeVolume(80, 90.f, m_sQueueSample.m_fDistance); - if (m_sQueueSample.m_nVolume) { - m_sQueueSample.m_nCounter = 2; - m_sQueueSample.m_nSampleIndex = SFX_CESNA_REV; - m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; - m_sQueueSample.m_bIs2D = false; - m_sQueueSample.m_nReleasingVolumeModificator = 0; - m_sQueueSample.m_nFrequency = 25000; - m_sQueueSample.m_nLoopCount = 0; - m_sQueueSample.m_nReleasingVolumeDivider = 4; - m_sQueueSample.m_nEmittingVolume = 80; - m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex); - m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex); - m_sQueueSample.m_fSpeedMultiplier = 8.0f; - m_sQueueSample.m_fSoundIntensity = 90.0f; - m_sQueueSample.m_bReleasingSoundFlag = false; - m_sQueueSample.m_bReverbFlag = true; - m_sQueueSample.m_bRequireReflection = false; - AddSampleToRequestedQueue(); - } - } - } -} - -void -cAudioManager::ProcessCinemaScriptObject(uint8 sound) -{ - uint8 rand; - - static uint8 counter = 0; - - uint32 time = CTimer::GetTimeInMilliseconds(); - if (time > gCinemaNextTime) { - switch (sound) { - case SCRIPT_SOUND_CINEMA_LOOP_S: - m_sQueueSample.m_fSoundIntensity = scriptObjectIntensityS; - break; - case SCRIPT_SOUND_CINEMA_LOOP_L: - m_sQueueSample.m_fSoundIntensity = scriptObjectIntensityL; - break; - default: - return; - } - float distSquared = GetDistanceSquared(m_sQueueSample.m_vecPos); - if (distSquared < SQR(m_sQueueSample.m_fSoundIntensity)) { - m_sQueueSample.m_fDistance = Sqrt(distSquared); - rand = m_anRandomTable[0] % 90 + 30; - m_sQueueSample.m_nVolume = ComputeVolume(rand, m_sQueueSample.m_fSoundIntensity, m_sQueueSample.m_fDistance); - if (m_sQueueSample.m_nVolume) { - m_sQueueSample.m_nSampleIndex = counter % 3 + SFX_CINEMA_BASS_1; - m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; - m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(m_sQueueSample.m_nSampleIndex); - m_sQueueSample.m_nFrequency += RandomDisplacement(m_sQueueSample.m_nFrequency / 4); - m_sQueueSample.m_nCounter = counter++; - m_sQueueSample.m_bIs2D = false; - m_sQueueSample.m_nLoopCount = 1; - m_sQueueSample.m_bReleasingSoundFlag = true; - m_sQueueSample.m_nReleasingVolumeModificator = 3; - m_sQueueSample.m_fSpeedMultiplier = 2.0f; - m_sQueueSample.m_nEmittingVolume = rand; - m_sQueueSample.m_nLoopStart = 0; - m_sQueueSample.m_nLoopEnd = -1; - m_sQueueSample.m_bReverbFlag = true; - m_sQueueSample.m_bRequireReflection = false; - AddSampleToRequestedQueue(); - gCinemaNextTime = time + 1000 + m_anRandomTable[3] % 4000; - } - } - } -} - -void -cAudioManager::ProcessCrane() -{ - CCrane *crane = (CCrane *)m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_pEntity; - float distSquared; - bool distCalculated = false; - static const int intensity = 80; - - if (crane) { - if (crane->m_nCraneStatus == CCrane::ACTIVATED) { - if (crane->m_nCraneState != CCrane::IDLE) { - m_sQueueSample.m_vecPos = crane->m_pCraneEntity->GetPosition(); - distSquared = GetDistanceSquared(m_sQueueSample.m_vecPos); - if (distSquared < SQR(intensity)) { - CalculateDistance(distCalculated, distSquared); - m_sQueueSample.m_nVolume = ComputeVolume(100, 80.f, m_sQueueSample.m_fDistance); - if (m_sQueueSample.m_nVolume) { - m_sQueueSample.m_nCounter = 0; - m_sQueueSample.m_nSampleIndex = SFX_CRANE_MAGNET; - m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; - m_sQueueSample.m_bIs2D = false; - m_sQueueSample.m_nReleasingVolumeModificator = 2; - m_sQueueSample.m_nFrequency = 6000; - m_sQueueSample.m_nLoopCount = 0; - m_sQueueSample.m_nEmittingVolume = 100; - m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex); - m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex); - m_sQueueSample.m_fSpeedMultiplier = 4.0f; - m_sQueueSample.m_fSoundIntensity = intensity; - m_sQueueSample.m_bReleasingSoundFlag = false; - m_sQueueSample.m_nReleasingVolumeDivider = 3; - m_sQueueSample.m_bReverbFlag = true; - m_sQueueSample.m_bRequireReflection = false; - AddSampleToRequestedQueue(); - } - if (m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_AudioEvents) { - m_sQueueSample.m_nCounter = 1; - m_sQueueSample.m_nSampleIndex = SFX_COL_CAR_2; - m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_COL_CAR_2); - m_sQueueSample.m_nLoopCount = 1; - m_sQueueSample.m_bReleasingSoundFlag = true; - m_sQueueSample.m_bReverbFlag = true; - m_sQueueSample.m_bRequireReflection = true; - AddSampleToRequestedQueue(); - } - } - } - } - } -} - -void -cAudioManager::ProcessDocksScriptObject(uint8 sound) -{ - uint32 time; - uint8 rand; - float distSquared; - - static uint32 counter = 0; - - time = CTimer::GetTimeInMilliseconds(); - if (time > gDocksNextTime) { - switch (sound) { - case SCRIPT_SOUND_DOCKS_LOOP_S: - m_sQueueSample.m_fSoundIntensity = scriptObjectIntensityS; - break; - case SCRIPT_SOUND_DOCKS_LOOP_L: - m_sQueueSample.m_fSoundIntensity = scriptObjectIntensityL; - break; - default: - return; - } - distSquared = GetDistanceSquared(m_sQueueSample.m_vecPos); - if (distSquared < SQR(m_sQueueSample.m_fSoundIntensity)) { - m_sQueueSample.m_fDistance = Sqrt(distSquared); - rand = m_anRandomTable[0] % 60 + 40; - m_sQueueSample.m_nVolume = ComputeVolume(rand, m_sQueueSample.m_fSoundIntensity, m_sQueueSample.m_fDistance); - if (m_sQueueSample.m_nVolume) { - m_sQueueSample.m_nSampleIndex = SFX_DOCKS_FOGHORN; - m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; - m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_DOCKS_FOGHORN); - m_sQueueSample.m_nFrequency += RandomDisplacement(m_sQueueSample.m_nFrequency / 8); - m_sQueueSample.m_nCounter = counter++; - m_sQueueSample.m_bIs2D = false; - m_sQueueSample.m_nLoopCount = 1; - m_sQueueSample.m_bReleasingSoundFlag = true; - m_sQueueSample.m_nReleasingVolumeModificator = 3; - m_sQueueSample.m_fSpeedMultiplier = 2.0f; - m_sQueueSample.m_nEmittingVolume = rand; - m_sQueueSample.m_nLoopStart = 0; - m_sQueueSample.m_nLoopEnd = -1; - m_sQueueSample.m_bReverbFlag = true; - m_sQueueSample.m_bRequireReflection = false; - AddSampleToRequestedQueue(); - gDocksNextTime = time + 10000 + m_anRandomTable[3] % 40000; - } - } - } -} - -bool -cAudioManager::ProcessEngineDamage(cVehicleParams *params) -{ - CAutomobile *veh; - uint8 engineStatus; - uint8 emittingVolume; - - if (params->m_fDistance >= SQR(engineDamageIntensity)) - return false; - veh = (CAutomobile *)params->m_pVehicle; - if (veh->bEngineOn) { - engineStatus = veh->Damage.GetEngineStatus(); - if (engineStatus > 250 || engineStatus < 100) - return true; - if (engineStatus < 225) { - m_sQueueSample.m_nSampleIndex = SFX_JUMBO_TAXI; - emittingVolume = 6; - m_sQueueSample.m_nReleasingVolumeModificator = 7; - m_sQueueSample.m_nFrequency = 40000; - } else { - emittingVolume = 60; - m_sQueueSample.m_nSampleIndex = SFX_CAR_ON_FIRE; - m_sQueueSample.m_nReleasingVolumeModificator = 7; - m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_CAR_ON_FIRE); - } - CalculateDistance(params->m_bDistanceCalculated, params->m_fDistance); - m_sQueueSample.m_nVolume = ComputeVolume(emittingVolume, engineDamageIntensity, m_sQueueSample.m_fDistance); - if (m_sQueueSample.m_nVolume) { - m_sQueueSample.m_nCounter = 28; - m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; - m_sQueueSample.m_bIs2D = false; - m_sQueueSample.m_nLoopCount = 0; - m_sQueueSample.m_nEmittingVolume = emittingVolume; - m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex); - m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex); - m_sQueueSample.m_fSpeedMultiplier = 2.0f; - m_sQueueSample.m_fSoundIntensity = engineDamageIntensity; - m_sQueueSample.m_bReleasingSoundFlag = false; - m_sQueueSample.m_nReleasingVolumeDivider = 3; - m_sQueueSample.m_bReverbFlag = true; - m_sQueueSample.m_bRequireReflection = false; - AddSampleToRequestedQueue(); - } - } - return true; -} - -void -cAudioManager::ProcessEntity(int32 id) -{ - if (m_asAudioEntities[id].m_nStatus) { - m_sQueueSample.m_nEntityIndex = id; - switch (m_asAudioEntities[id].m_nType) { - case AUDIOTYPE_PHYSICAL: - if (!m_nUserPause) { - m_sQueueSample.m_bReverbFlag = true; - ProcessPhysical(id); - } - break; - case AUDIOTYPE_EXPLOSION: - if (!m_nUserPause) { - m_sQueueSample.m_bReverbFlag = true; - ProcessExplosions(id); - } - break; - case AUDIOTYPE_FIRE: - if (!m_nUserPause) { - m_sQueueSample.m_bReverbFlag = true; - ProcessFires(id); - } - break; - case AUDIOTYPE_WEATHER: - if (!m_nUserPause) { - m_sQueueSample.m_bReverbFlag = true; - ProcessWeather(id); - } - break; - case AUDIOTYPE_CRANE: - if (!m_nUserPause) { - m_sQueueSample.m_bReverbFlag = true; - ProcessCrane(); - } - break; - case AUDIOTYPE_SCRIPTOBJECT: - if (!m_nUserPause) { - m_sQueueSample.m_bReverbFlag = true; - ProcessScriptObject(id); - } - break; - case AUDIOTYPE_BRIDGE: - if (!m_nUserPause) { - m_sQueueSample.m_bReverbFlag = true; - ProcessBridge(); - } - break; - case AUDIOTYPE_FRONTEND: - m_sQueueSample.m_bReverbFlag = false; - ProcessFrontEnd(); - break; - case AUDIOTYPE_PROJECTILE: - if (!m_nUserPause) { - m_sQueueSample.m_bReverbFlag = true; - ProcessProjectiles(); - } - break; - case AUDIOTYPE_GARAGE: - if (!m_nUserPause) - ProcessGarages(); - break; - case AUDIOTYPE_FIREHYDRANT: - if (!m_nUserPause) { - m_sQueueSample.m_bReverbFlag = true; - ProcessFireHydrant(); - } - break; - case AUDIOTYPE_WATERCANNON: - if (!m_nUserPause) { - m_sQueueSample.m_bReverbFlag = true; - ProcessWaterCannon(id); - } - break; - default: - return; - } - } -} - -void -cAudioManager::ProcessExplosions(int32 explosion) -{ - uint8 type; - CVector *pos; - float distSquared; - - for (uint8 i = 0; i < ARRAY_SIZE(gaExplosion); i++) { - if (CExplosion::GetExplosionActiveCounter(i) == 1) { - CExplosion::ResetExplosionActiveCounter(i); - type = CExplosion::GetExplosionType(i); - switch (type) { - case EXPLOSION_GRENADE: - case EXPLOSION_ROCKET: - case EXPLOSION_BARREL: - case EXPLOSION_TANK_GRENADE: - m_sQueueSample.m_fSoundIntensity = 400.0f; - m_sQueueSample.m_nSampleIndex = SFX_EXPLOSION_2; - m_sQueueSample.m_nFrequency = RandomDisplacement(2000) + 38000; - m_sQueueSample.m_nReleasingVolumeModificator = 0; - m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; - break; - case EXPLOSION_MOLOTOV: - m_sQueueSample.m_fSoundIntensity = 200.0f; - m_sQueueSample.m_nSampleIndex = SFX_EXPLOSION_3; - m_sQueueSample.m_nFrequency = RandomDisplacement(1000) + 19000; - m_sQueueSample.m_nReleasingVolumeModificator = 0; - m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; - break; - case EXPLOSION_MINE: - case EXPLOSION_HELI_BOMB: - m_sQueueSample.m_fSoundIntensity = 300.0f; - m_sQueueSample.m_nSampleIndex = SFX_ROCKET_LEFT; - m_sQueueSample.m_nFrequency = RandomDisplacement(1000) + 12347; - m_sQueueSample.m_nReleasingVolumeModificator = 0; - m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; - break; - default: - m_sQueueSample.m_fSoundIntensity = 400.0f; - m_sQueueSample.m_nSampleIndex = SFX_EXPLOSION_1; - m_sQueueSample.m_nFrequency = RandomDisplacement(2000) + 38000; - if (type == EXPLOSION_HELI) - m_sQueueSample.m_nFrequency = 8 * m_sQueueSample.m_nFrequency / 10; - m_sQueueSample.m_nReleasingVolumeModificator = 0; - m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; - break; - } - pos = CExplosion::GetExplosionPosition(i); - m_sQueueSample.m_vecPos = *pos; - distSquared = GetDistanceSquared(m_sQueueSample.m_vecPos); - if (distSquared < SQR(m_sQueueSample.m_fSoundIntensity)) { - m_sQueueSample.m_fDistance = Sqrt(distSquared); - m_sQueueSample.m_nVolume = ComputeVolume(maxVolume, m_sQueueSample.m_fSoundIntensity, m_sQueueSample.m_fDistance); - if (m_sQueueSample.m_nVolume) { - m_sQueueSample.m_nCounter = i; - m_sQueueSample.m_fSpeedMultiplier = 2.0f; - m_sQueueSample.m_bIs2D = false; - m_sQueueSample.m_nLoopCount = 1; - m_sQueueSample.m_bReleasingSoundFlag = true; - m_sQueueSample.m_bReverbFlag = true; - m_sQueueSample.m_nEmittingVolume = maxVolume; - m_sQueueSample.m_nLoopStart = 0; - m_sQueueSample.m_nLoopEnd = -1; - m_sQueueSample.m_bReverbFlag = true; - m_sQueueSample.m_bRequireReflection = true; - AddSampleToRequestedQueue(); - } - } - } - } -} - -void -cAudioManager::ProcessFireHydrant() -{ - float distSquared; - bool distCalculated = false; - static const int intensity = 35; - - m_sQueueSample.m_vecPos = ((CEntity *)m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_pEntity)->GetPosition(); - distSquared = GetDistanceSquared(m_sQueueSample.m_vecPos); - if (distSquared < SQR(intensity)) { - CalculateDistance(distCalculated, distSquared); - m_sQueueSample.m_nVolume = ComputeVolume(40, 35.f, m_sQueueSample.m_fDistance); - if (m_sQueueSample.m_nVolume) { - m_sQueueSample.m_nCounter = 0; - m_sQueueSample.m_nSampleIndex = SFX_JUMBO_TAXI; - m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; - m_sQueueSample.m_bIs2D = false; - m_sQueueSample.m_nReleasingVolumeModificator = 4; - m_sQueueSample.m_nFrequency = 15591; - m_sQueueSample.m_nLoopCount = 0; - m_sQueueSample.m_nEmittingVolume = 40; - m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex); - m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex); - m_sQueueSample.m_fSpeedMultiplier = 2.0f; - m_sQueueSample.m_fSoundIntensity = intensity; - m_sQueueSample.m_bReleasingSoundFlag = false; - m_sQueueSample.m_nReleasingVolumeDivider = 3; - m_sQueueSample.m_bReverbFlag = true; - m_sQueueSample.m_bRequireReflection = false; - AddSampleToRequestedQueue(); - } - } -} - -void cAudioManager::ProcessFires(int32) -{ - CEntity *entity; - uint8 emittingVol; - float distSquared; - - for (uint8 i = 0; i < NUM_FIRES; i++) { - if (gFireManager.m_aFires[i].m_bIsOngoing && gFireManager.m_aFires[i].m_bAudioSet) { - entity = gFireManager.m_aFires[i].m_pEntity; - if (entity) { - switch (entity->GetType()) { - case ENTITY_TYPE_BUILDING: - m_sQueueSample.m_fSoundIntensity = 50.0f; - m_sQueueSample.m_nSampleIndex = SFX_CAR_ON_FIRE; - emittingVol = 100; - m_sQueueSample.m_nFrequency = 8 * SampleManager.GetSampleBaseFrequency(SFX_CAR_ON_FIRE) / 10; - m_sQueueSample.m_nFrequency += i * (m_sQueueSample.m_nFrequency / 64); - m_sQueueSample.m_nReleasingVolumeModificator = 6; - break; - case ENTITY_TYPE_PED: - m_sQueueSample.m_fSoundIntensity = 25.0f; - m_sQueueSample.m_nSampleIndex = SFX_PED_ON_FIRE; - m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_PED_ON_FIRE); - emittingVol = 60; - m_sQueueSample.m_nFrequency += i * (m_sQueueSample.m_nFrequency / 64); - m_sQueueSample.m_nReleasingVolumeModificator = 10; - break; - default: - m_sQueueSample.m_fSoundIntensity = 50.0f; - m_sQueueSample.m_nSampleIndex = SFX_CAR_ON_FIRE; - m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_CAR_ON_FIRE); - m_sQueueSample.m_nFrequency += i * (m_sQueueSample.m_nFrequency / 64); - emittingVol = 80; - m_sQueueSample.m_nReleasingVolumeModificator = 8; - } - } else { - m_sQueueSample.m_fSoundIntensity = 50.0f; - m_sQueueSample.m_nSampleIndex = SFX_CAR_ON_FIRE; - m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_CAR_ON_FIRE); - m_sQueueSample.m_nFrequency += i * (m_sQueueSample.m_nFrequency / 64); - emittingVol = 80; - m_sQueueSample.m_nReleasingVolumeModificator = 8; - } - m_sQueueSample.m_vecPos = gFireManager.m_aFires[i].m_vecPos; - distSquared = GetDistanceSquared(m_sQueueSample.m_vecPos); - if (distSquared < SQR(m_sQueueSample.m_fSoundIntensity)) { - m_sQueueSample.m_fDistance = Sqrt(distSquared); - m_sQueueSample.m_nVolume = ComputeVolume(emittingVol, m_sQueueSample.m_fSoundIntensity, m_sQueueSample.m_fDistance); - if (m_sQueueSample.m_nVolume) { - m_sQueueSample.m_nCounter = i; - m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; - m_sQueueSample.m_fSpeedMultiplier = 2.0f; - m_sQueueSample.m_nReleasingVolumeDivider = 10; - m_sQueueSample.m_bIs2D = false; - m_sQueueSample.m_nLoopCount = 0; - m_sQueueSample.m_bReleasingSoundFlag = false; - m_sQueueSample.m_nEmittingVolume = emittingVol; - m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex); - m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex); - m_sQueueSample.m_bReverbFlag = true; - m_sQueueSample.m_bRequireReflection = false; - AddSampleToRequestedQueue(); - } - } - } - } -} - -void -cAudioManager::ProcessFrontEnd() -{ - bool stereo; - bool processedPickup; - bool processedMission; - int16 sample; - - static uint8 counter = 0; - static uint32 cPickupNextFrame = 0; - static uint32 cPartMisComNextFrame = 0; - - for (uint32 i = 0; i < m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_AudioEvents; i++) { - processedPickup = false; - stereo = false; - processedMission = false; - switch (m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_awAudioEvent[i]) { - case SOUND_WEAPON_SNIPER_SHOT_NO_ZOOM: - m_sQueueSample.m_nSampleIndex = SFX_ERROR_FIRE_RIFLE; - break; - case SOUND_WEAPON_ROCKET_SHOT_NO_ZOOM: - m_sQueueSample.m_nSampleIndex = SFX_ERROR_FIRE_ROCKET_LAUNCHER; - break; - case SOUND_GARAGE_NO_MONEY: - case SOUND_GARAGE_BAD_VEHICLE: - case SOUND_GARAGE_BOMB_ALREADY_SET: - m_sQueueSample.m_nSampleIndex = SFX_PICKUP_ERROR_LEFT; - stereo = true; - break; - case SOUND_GARAGE_OPENING: - case SOUND_GARAGE_BOMB1_SET: - case SOUND_GARAGE_BOMB2_SET: - case SOUND_GARAGE_BOMB3_SET: - case SOUND_41: - case SOUND_GARAGE_VEHICLE_DECLINED: - case SOUND_GARAGE_VEHICLE_ACCEPTED: - case SOUND_PICKUP_HEALTH: - case SOUND_4B: - case SOUND_PICKUP_ADRENALINE: - case SOUND_PICKUP_ARMOUR: - case SOUND_EVIDENCE_PICKUP: - case SOUND_UNLOAD_GOLD: - m_sQueueSample.m_nSampleIndex = SFX_PICKUP_2_LEFT; - processedPickup = true; - stereo = true; - break; - case SOUND_PICKUP_WEAPON_BOUGHT: - case SOUND_PICKUP_WEAPON: - m_sQueueSample.m_nSampleIndex = SFX_PICKUP_1_LEFT; - processedPickup = true; - stereo = true; - break; - case SOUND_4A: - m_sQueueSample.m_nSampleIndex = SFX_PICKUP_ERROR_LEFT; - processedPickup = true; - stereo = true; - break; - case SOUND_PICKUP_BONUS: - case SOUND_PICKUP_MONEY: - case SOUND_PICKUP_HIDDEN_PACKAGE: - case SOUND_PICKUP_PACMAN_PILL: - case SOUND_PICKUP_PACMAN_PACKAGE: - case SOUND_PICKUP_FLOAT_PACKAGE: - m_sQueueSample.m_nSampleIndex = SFX_PICKUP_3_LEFT; - processedPickup = true; - stereo = true; - break; - case SOUND_PAGER: - m_sQueueSample.m_nSampleIndex = SFX_PAGER; - break; - case SOUND_RACE_START_3: - case SOUND_RACE_START_2: - case SOUND_RACE_START_1: - case SOUND_CLOCK_TICK: - m_sQueueSample.m_nSampleIndex = SFX_TIMER_BEEP; - break; - case SOUND_RACE_START_GO: - m_sQueueSample.m_nSampleIndex = SFX_PART_MISSION_COMPLETE; - break; - case SOUND_PART_MISSION_COMPLETE: - m_sQueueSample.m_nSampleIndex = SFX_PART_MISSION_COMPLETE; - processedMission = true; - break; - case SOUND_FRONTEND_MENU_STARTING: - m_sQueueSample.m_nSampleIndex = SFX_START_BUTTON_LEFT; - stereo = true; - break; - case SOUND_FRONTEND_MENU_COMPLETED: - m_sQueueSample.m_nSampleIndex = SFX_PAGE_CHANGE_AND_BACK_LEFT; - stereo = true; - break; - case SOUND_FRONTEND_MENU_DENIED: - m_sQueueSample.m_nSampleIndex = SFX_HIGHLIGHT_LEFT; - stereo = true; - break; - case SOUND_FRONTEND_MENU_SUCCESS: - m_sQueueSample.m_nSampleIndex = SFX_SELECT_LEFT; - stereo = true; - break; - case SOUND_FRONTEND_EXIT: - m_sQueueSample.m_nSampleIndex = SFX_SUB_MENU_BACK_LEFT; - stereo = true; - break; - case SOUND_9A: - m_sQueueSample.m_nSampleIndex = SFX_STEREO_LEFT; - stereo = true; - break; - case SOUND_9B: - m_sQueueSample.m_nSampleIndex = SFX_MONO; - break; - case SOUND_FRONTEND_AUDIO_TEST: - m_sQueueSample.m_nSampleIndex = m_anRandomTable[0] % 3 + SFX_NOISE_BURST_1; - break; - case SOUND_FRONTEND_FAIL: - m_sQueueSample.m_nSampleIndex = SFX_ERROR_LEFT; - stereo = true; - break; - case SOUND_FRONTEND_NO_RADIO: - case SOUND_FRONTEND_RADIO_CHANGE: - m_sQueueSample.m_nSampleIndex = SFX_RADIO_CLICK; - break; - case SOUND_A0: - m_sQueueSample.m_nSampleIndex = SFX_INFO; - break; - default: - continue; - } - - if (processedPickup) { - if (m_FrameCounter <= cPickupNextFrame) - continue; - cPickupNextFrame = m_FrameCounter + 5; - } else if (processedMission) { - if (m_FrameCounter <= cPartMisComNextFrame) - continue; - cPartMisComNextFrame = m_FrameCounter + 5; - } - - sample = m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_awAudioEvent[i]; - if (sample == SFX_RAIN) { - m_sQueueSample.m_nFrequency = 28509; - } else if (sample == SFX_PICKUP_1_LEFT) { - if (1.f == m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_afVolume[i]) - m_sQueueSample.m_nFrequency = 32000; - else - m_sQueueSample.m_nFrequency = 48000; - } else { - m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(m_sQueueSample.m_nSampleIndex); - } - m_sQueueSample.m_nVolume = 110; - m_sQueueSample.m_nCounter = counter++; - m_sQueueSample.m_nLoopCount = 1; - m_sQueueSample.m_bReleasingSoundFlag = true; - m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; - m_sQueueSample.m_nReleasingVolumeModificator = 0; - m_sQueueSample.m_bIs2D = true; - m_sQueueSample.m_nEmittingVolume = m_sQueueSample.m_nVolume; - m_sQueueSample.m_nLoopStart = 0; - m_sQueueSample.m_nLoopEnd = -1; - if (stereo) - m_sQueueSample.m_nOffset = m_anRandomTable[0] & 31; - else - m_sQueueSample.m_nOffset = 63; - m_sQueueSample.m_bReverbFlag = false; - m_sQueueSample.m_bRequireReflection = false; - AddSampleToRequestedQueue(); - if (stereo) { - ++m_sQueueSample.m_nSampleIndex; - m_sQueueSample.m_nCounter = counter++; - m_sQueueSample.m_nOffset = maxVolume - m_sQueueSample.m_nOffset; - AddSampleToRequestedQueue(); - } - } -} - -void -cAudioManager::ProcessGarages() -{ - CEntity *entity; - eGarageState state; - uint32 sampleIndex; - uint8 j; - float distSquared; - bool distCalculated; - - static uint8 iSound = 32; - -#define LOOP_HELPER \ - for (j = 0; j < m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_AudioEvents; ++j) { \ - switch (m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_awAudioEvent[j]) { \ - case SOUND_GARAGE_DOOR_CLOSED: \ - case SOUND_GARAGE_DOOR_OPENED: \ - if (distSquared < 6400.f) { \ - CalculateDistance(distCalculated, distSquared); \ - m_sQueueSample.m_nVolume = ComputeVolume(60, 80.f, m_sQueueSample.m_fDistance); \ - if (m_sQueueSample.m_nVolume) { \ - if (CGarages::aGarages[i].m_eGarageType == GARAGE_CRUSHER) { \ - m_sQueueSample.m_nSampleIndex = SFX_COL_CAR_PANEL_2; \ - m_sQueueSample.m_nFrequency = 6735; \ - } else if (m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_awAudioEvent[j] == 69) { \ - m_sQueueSample.m_nSampleIndex = SFX_COL_CAR_PANEL_2; \ - m_sQueueSample.m_nFrequency = 22000; \ - } else { \ - m_sQueueSample.m_nSampleIndex = SFX_COL_GARAGE_DOOR_1; \ - m_sQueueSample.m_nFrequency = 18000; \ - } \ - m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; \ - m_sQueueSample.m_nReleasingVolumeModificator = 4; \ - m_sQueueSample.m_nEmittingVolume = 60; \ - m_sQueueSample.m_fSpeedMultiplier = 0.0f; \ - m_sQueueSample.m_fSoundIntensity = 80.0f; \ - /*m_sQueueSample.m_nReleasingVolumeModificator = 4;*/ \ - m_sQueueSample.m_bReverbFlag = true; \ - /*m_sQueueSample.m_bReverbFlag = true;*/ \ - m_sQueueSample.m_bIs2D = false; \ - m_sQueueSample.m_bReleasingSoundFlag = true; \ - m_sQueueSample.m_nLoopCount = 1; \ - m_sQueueSample.m_nLoopStart = 0; \ - m_sQueueSample.m_nLoopEnd = -1; \ - m_sQueueSample.m_nCounter = iSound++; \ - if (iSound < 32) \ - iSound = 32; \ - m_sQueueSample.m_bRequireReflection = true; \ - AddSampleToRequestedQueue(); \ - } \ - } \ - break; \ - default: \ - continue; \ - } \ - } - - for (uint32 i = 0; i < CGarages::NumGarages; ++i) { - if (CGarages::aGarages[i].m_eGarageType == GARAGE_NONE) - continue; - entity = CGarages::aGarages[i].m_pDoor1; - if (!entity) - continue; - m_sQueueSample.m_vecPos = entity->GetPosition(); - distCalculated = false; - distSquared = GetDistanceSquared(m_sQueueSample.m_vecPos); - if (distSquared < 6400.f) { - state = CGarages::aGarages[i].m_eGarageState; - if (state == GS_OPENING || state == GS_CLOSING || state == GS_AFTERDROPOFF) { - CalculateDistance(distCalculated, distSquared); - m_sQueueSample.m_nVolume = ComputeVolume(90, 80.f, m_sQueueSample.m_fDistance); - if (m_sQueueSample.m_nVolume) { - if (CGarages::aGarages[i].m_eGarageType == GARAGE_CRUSHER) { - if (CGarages::aGarages[i].m_eGarageState == GS_AFTERDROPOFF) { - if (!(m_FrameCounter & 1)) { - LOOP_HELPER - continue; - } - if (m_anRandomTable[1] & 1) { - sampleIndex = m_anRandomTable[2] % 5 + SFX_COL_CAR_1; - } else { - sampleIndex = m_anRandomTable[2] % 6 + SFX_COL_CAR_PANEL_1; - } - m_sQueueSample.m_nSampleIndex = sampleIndex; - m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(m_sQueueSample.m_nSampleIndex) / 2; - m_sQueueSample.m_nFrequency += RandomDisplacement(m_sQueueSample.m_nFrequency / 16); - m_sQueueSample.m_nLoopCount = 1; - m_sQueueSample.m_bReleasingSoundFlag = true; - m_sQueueSample.m_nCounter = iSound++; - if (iSound < 32) - iSound = 32; - m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; - m_sQueueSample.m_bIs2D = false; - m_sQueueSample.m_nReleasingVolumeModificator = 3; - m_sQueueSample.m_nEmittingVolume = 90; - m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex); - m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex); - m_sQueueSample.m_fSpeedMultiplier = 2.0f; - m_sQueueSample.m_fSoundIntensity = 80.0f; - m_sQueueSample.m_bReverbFlag = true; - m_sQueueSample.m_bRequireReflection = false; - AddSampleToRequestedQueue(); - LOOP_HELPER - continue; - } - m_sQueueSample.m_nSampleIndex = SFX_FISHING_BOAT_IDLE; - m_sQueueSample.m_nFrequency = 6543; - } else { - m_sQueueSample.m_nSampleIndex = SFX_GARAGE_DOOR_LOOP; - m_sQueueSample.m_nFrequency = 13961; - } - m_sQueueSample.m_nCounter = i; - m_sQueueSample.m_nLoopCount = 0; - m_sQueueSample.m_nReleasingVolumeDivider = 3; - m_sQueueSample.m_bReleasingSoundFlag = false; - m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; - m_sQueueSample.m_bIs2D = false; - m_sQueueSample.m_nReleasingVolumeModificator = 3; - m_sQueueSample.m_nEmittingVolume = 90; - m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex); - m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex); - m_sQueueSample.m_fSpeedMultiplier = 2.0f; - m_sQueueSample.m_fSoundIntensity = 80.0f; - m_sQueueSample.m_bReverbFlag = true; - m_sQueueSample.m_bRequireReflection = false; - AddSampleToRequestedQueue(); - } - } - LOOP_HELPER - } - } -#undef LOOP_HELPER -} - -struct tHelicopterSampleData { - float m_fMaxDistance; - float m_fBaseDistance; - uint8 m_bBaseVolume; -}; - -bool -cAudioManager::ProcessHelicopter(cVehicleParams *params) -{ - CHeli *heli; - float MaxDist; - float dist; - float baseDist; - int32 emittingVol; - static const tHelicopterSampleData gHeliSfxRanges[3] = {{400.f, 380.f, 100}, {100.f, 70.f, maxVolume}, {60.f, 30.f, maxVolume}}; - - if (gHeliSfxRanges[0].m_fMaxDistance * gHeliSfxRanges[0].m_fMaxDistance <= params->m_fDistance) - return false; - - CalculateDistance(params->m_bDistanceCalculated, params->m_fDistance); - heli = (CHeli *)params->m_pVehicle; - for (uint32 i = 0; i < ARRAY_SIZE(gHeliSfxRanges); i++) { - MaxDist = gHeliSfxRanges[i].m_fMaxDistance; - dist = m_sQueueSample.m_fDistance; - if (dist >= MaxDist) - return true; - baseDist = gHeliSfxRanges[i].m_fBaseDistance; - if (dist < baseDist) - emittingVol = (gHeliSfxRanges[i].m_bBaseVolume * ((MaxDist - dist) / (MaxDist - baseDist))); - else - emittingVol = gHeliSfxRanges[i].m_bBaseVolume; - - m_sQueueSample.m_nVolume = ComputeVolume(emittingVol, gHeliSfxRanges[i].m_fMaxDistance, m_sQueueSample.m_fDistance); - if (m_sQueueSample.m_nVolume) { - m_sQueueSample.m_nCounter = i + 65; - m_sQueueSample.m_nSampleIndex = i + SFX_HELI_1; - m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; - m_sQueueSample.m_bIs2D = false; - m_sQueueSample.m_nReleasingVolumeModificator = 0; - m_sQueueSample.m_nFrequency = 1200 * heli->m_nHeliId + SampleManager.GetSampleBaseFrequency(m_sQueueSample.m_nSampleIndex); - m_sQueueSample.m_nLoopCount = 0; - m_sQueueSample.m_nEmittingVolume = emittingVol; - m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex); - m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex); - m_sQueueSample.m_fSpeedMultiplier = 6.0f; - m_sQueueSample.m_fSoundIntensity = gHeliSfxRanges[i].m_fMaxDistance; - m_sQueueSample.m_bReleasingSoundFlag = false; - m_sQueueSample.m_nReleasingVolumeDivider = 3; - m_sQueueSample.m_bReverbFlag = true; - m_sQueueSample.m_bRequireReflection = false; - AddSampleToRequestedQueue(); - } - } - return true; -} - -void -cAudioManager::ProcessHomeScriptObject(uint8 sound) -{ - uint32 time; - uint8 rand; - float dist; - - static uint8 counter = 0; - - time = CTimer::GetTimeInMilliseconds(); - if (time > gHomeNextTime) { - switch (sound) { - case SCRIPT_SOUND_HOME_LOOP_S: - m_sQueueSample.m_fSoundIntensity = scriptObjectIntensityS; - break; - case SCRIPT_SOUND_HOME_LOOP_L: - m_sQueueSample.m_fSoundIntensity = scriptObjectIntensityL; - break; - default: - return; - } - dist = GetDistanceSquared(m_sQueueSample.m_vecPos); - if (dist < SQR(m_sQueueSample.m_fSoundIntensity)) { - m_sQueueSample.m_fDistance = Sqrt(dist); - rand = m_anRandomTable[0] % 30 + 40; - m_sQueueSample.m_nVolume = ComputeVolume(rand, m_sQueueSample.m_fSoundIntensity, m_sQueueSample.m_fDistance); - if (m_sQueueSample.m_nVolume) { - m_sQueueSample.m_nSampleIndex = m_anRandomTable[0] % 5 + SFX_HOME_1; - m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; - m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(m_sQueueSample.m_nSampleIndex); - m_sQueueSample.m_nFrequency += RandomDisplacement(m_sQueueSample.m_nFrequency / 16); - m_sQueueSample.m_nCounter = counter++; - m_sQueueSample.m_bIs2D = false; - m_sQueueSample.m_nLoopCount = 1; - m_sQueueSample.m_bReleasingSoundFlag = true; - m_sQueueSample.m_nReleasingVolumeModificator = 3; - m_sQueueSample.m_fSpeedMultiplier = 0.0f; - m_sQueueSample.m_nEmittingVolume = rand; - m_sQueueSample.m_nLoopStart = 0; - m_sQueueSample.m_nLoopEnd = -1; - m_sQueueSample.m_bReverbFlag = true; - m_sQueueSample.m_bRequireReflection = true; - AddSampleToRequestedQueue(); - gHomeNextTime = time + 1000 + m_anRandomTable[3] % 4000; - } - } - } -} - -void -cAudioManager::ProcessJumbo(cVehicleParams *params) -{ - CPlane *plane; - float position; - - if (params->m_fDistance < 193600.0f) { - CalculateDistance(params->m_bDistanceCalculated, params->m_fDistance); - plane = (CPlane *)params->m_pVehicle; - DoJumboVolOffset(); - position = PlanePathPosition[plane->m_nPlaneId]; - if (position <= TakeOffPoint) { - if (plane->m_fSpeed <= 0.10334f) { - ProcessJumboTaxi(); - return; - } - - ProcessJumboAccel(plane); - } else if (300.0f + TakeOffPoint >= position) { - ProcessJumboTakeOff(plane); - } else if (LandingPoint - 350.0f >= position) { - ProcessJumboFlying(); - } else { - if (position > LandingPoint) { - if (plane->m_fSpeed > 0.10334f) { - ProcessJumboDecel(plane); - return; - } - ProcessJumboTaxi(); - return; - } - ProcessJumboLanding(plane); - } - } -} - -void -cAudioManager::ProcessJumboAccel(CPlane *plane) -{ - int32 engineFreq; - int32 vol; - float whineSoundFreq; - float modificator; - - if (SetupJumboFlySound(20)) { - modificator = (plane->m_fSpeed - 0.10334f) * 1.676f; - if (modificator > 1.0f) - modificator = 1.0f; - if (SetupJumboRumbleSound(maxVolume * modificator) && SetupJumboTaxiSound((1.0f - modificator) * 75.f)) { - if (modificator < 0.2f) { - whineSoundFreq = modificator * 5.f * 14600.0f + 29500; - vol = modificator * 5.f * maxVolume; - engineFreq = modificator * 5.f * 6050.f + 16000; - } else { - whineSoundFreq = 44100; - engineFreq = 22050; - vol = maxVolume; - } - SetupJumboEngineSound(vol, engineFreq); - SetupJumboWhineSound(18, whineSoundFreq); - } - } -} - -void -cAudioManager::ProcessJumboDecel(CPlane *plane) -{ - if (SetupJumboFlySound(20) && SetupJumboTaxiSound(75)) { - const float modificator = Min(1.f, (plane->m_fSpeed - 0.10334f) * 1.676f); - SetupJumboEngineSound(maxVolume * modificator, 6050.f * modificator + 16000); - SetupJumboWhineSound(18, 29500); - } -} - -void -cAudioManager::ProcessJumboFlying() -{ - if (SetupJumboFlySound(maxVolume)) - SetupJumboEngineSound(63, 22050); -} - -void -cAudioManager::ProcessJumboLanding(CPlane *plane) -{ - const float modificator = (LandingPoint - PlanePathPosition[plane->m_nPlaneId]) / 350.f; - if (SetupJumboFlySound(107.f * modificator + 20)) { - if (SetupJumboTaxiSound(75.f * (1.f - modificator))) { - SetupJumboEngineSound(maxVolume, 22050); - SetupJumboWhineSound(18.f * (1.f - modificator), 14600.f * modificator + 29500); - } - } -} - -void -cAudioManager::ProcessJumboTakeOff(CPlane *plane) -{ - const float modificator = (PlanePathPosition[plane->m_nPlaneId] - TakeOffPoint) / 300.f; - - if (SetupJumboFlySound((107.f * modificator) + 20) && SetupJumboRumbleSound(maxVolume * (1.f - modificator))) { - if (SetupJumboEngineSound(maxVolume, 22050)) - SetupJumboWhineSound(18.f * (1.f - modificator), 44100); - } -} - -void -cAudioManager::ProcessJumboTaxi() -{ - if (SetupJumboFlySound(20)) { - if (SetupJumboTaxiSound(75)) - SetupJumboWhineSound(18, 29500); - } -} - -void -cAudioManager::ProcessLaunderetteScriptObject(uint8 sound) -{ - switch (sound) { - case SCRIPT_SOUND_LAUNDERETTE_LOOP_S: - case SCRIPT_SOUND_LAUNDERETTE_LOOP_L: - m_sQueueSample.m_fSoundIntensity = 30.0f; - break; - default: - return; - } - float distSquared = GetDistanceSquared(m_sQueueSample.m_vecPos); - if (distSquared < SQR(m_sQueueSample.m_fSoundIntensity)) { - m_sQueueSample.m_fDistance = Sqrt(distSquared); - m_sQueueSample.m_nVolume = ComputeVolume(45, m_sQueueSample.m_fSoundIntensity, m_sQueueSample.m_fDistance); - if (m_sQueueSample.m_nVolume) { - m_sQueueSample.m_nSampleIndex = SFX_LAUNDERETTE_LOOP; - m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; - m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_LAUNDERETTE_LOOP); - m_sQueueSample.m_nCounter = 0; - m_sQueueSample.m_bIs2D = false; - m_sQueueSample.m_nLoopCount = 0; - m_sQueueSample.m_bReleasingSoundFlag = false; - m_sQueueSample.m_nReleasingVolumeModificator = 5; - m_sQueueSample.m_fSpeedMultiplier = 2.0f; - m_sQueueSample.m_nEmittingVolume = 45; - m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex); - m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex); - m_sQueueSample.m_bReverbFlag = true; - m_sQueueSample.m_bRequireReflection = false; - AddSampleToRequestedQueue(); - } - m_sQueueSample.m_nVolume = ComputeVolume(110, m_sQueueSample.m_fSoundIntensity, m_sQueueSample.m_fDistance); - if (m_sQueueSample.m_nVolume) { - m_sQueueSample.m_nSampleIndex = SFX_LAUNDERETTE_SONG_LOOP; - m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; - m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_LAUNDERETTE_SONG_LOOP); - m_sQueueSample.m_nCounter = 1; - m_sQueueSample.m_bIs2D = false; - m_sQueueSample.m_nLoopCount = 0; - m_sQueueSample.m_bReleasingSoundFlag = false; - m_sQueueSample.m_nReleasingVolumeModificator = 3; - m_sQueueSample.m_fSpeedMultiplier = 2.0f; - m_sQueueSample.m_nEmittingVolume = 110; - m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex); - m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex); - m_sQueueSample.m_bReverbFlag = true; - m_sQueueSample.m_bRequireReflection = false; - AddSampleToRequestedQueue(); - } - } -} - -void -cAudioManager::ProcessLoopingScriptObject(uint8 sound) -{ - uint8 emittingVolume; - float distSquared; - - switch (sound) { - case SCRIPT_SOUND_PARTY_1_LOOP_S: - m_sQueueSample.m_fSoundIntensity = 30.0f; - m_sQueueSample.m_nSampleIndex = SFX_CLUB_1; - m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; - emittingVolume = maxVolume; - m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_CLUB_1); - m_sQueueSample.m_nReleasingVolumeModificator = 3; - m_sQueueSample.m_nReleasingVolumeDivider = 3; - m_sQueueSample.m_fSpeedMultiplier = 2.0f; - break; - case SCRIPT_SOUND_PARTY_1_LOOP_L: - m_sQueueSample.m_fSoundIntensity = 80.0f; - m_sQueueSample.m_nSampleIndex = SFX_CLUB_1; - m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; - emittingVolume = maxVolume; - m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_CLUB_1); - m_sQueueSample.m_nReleasingVolumeModificator = 3; - m_sQueueSample.m_nReleasingVolumeDivider = 3; - m_sQueueSample.m_fSpeedMultiplier = 2.0f; - break; - case SCRIPT_SOUND_PARTY_2_LOOP_S: - m_sQueueSample.m_fSoundIntensity = 30.0f; - m_sQueueSample.m_nSampleIndex = SFX_CLUB_2; - m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; - emittingVolume = maxVolume; - m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_CLUB_2); - m_sQueueSample.m_nReleasingVolumeModificator = 3; - m_sQueueSample.m_nReleasingVolumeDivider = 3; - m_sQueueSample.m_fSpeedMultiplier = 2.0f; - break; - case SCRIPT_SOUND_PARTY_2_LOOP_L: - m_sQueueSample.m_fSoundIntensity = 80.0f; - m_sQueueSample.m_nSampleIndex = SFX_CLUB_2; - m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; - emittingVolume = maxVolume; - m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_CLUB_2); - m_sQueueSample.m_nReleasingVolumeModificator = 3; - m_sQueueSample.m_nReleasingVolumeDivider = 3; - m_sQueueSample.m_fSpeedMultiplier = 2.0f; - break; - case SCRIPT_SOUND_PARTY_3_LOOP_S: - m_sQueueSample.m_fSoundIntensity = 30.0f; - m_sQueueSample.m_nSampleIndex = SFX_CLUB_3; - m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; - emittingVolume = maxVolume; - m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_CLUB_3); - m_sQueueSample.m_nReleasingVolumeModificator = 3; - m_sQueueSample.m_nReleasingVolumeDivider = 3; - m_sQueueSample.m_fSpeedMultiplier = 2.0f; - break; - case SCRIPT_SOUND_PARTY_3_LOOP_L: - m_sQueueSample.m_fSoundIntensity = 80.0f; - m_sQueueSample.m_nSampleIndex = SFX_CLUB_3; - m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; - emittingVolume = maxVolume; - m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_CLUB_3); - m_sQueueSample.m_nReleasingVolumeModificator = 3; - m_sQueueSample.m_nReleasingVolumeDivider = 3; - m_sQueueSample.m_fSpeedMultiplier = 2.0f; - break; - case SCRIPT_SOUND_PARTY_4_LOOP_S: - m_sQueueSample.m_fSoundIntensity = 30.0f; - m_sQueueSample.m_nSampleIndex = SFX_CLUB_4; - m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; - emittingVolume = maxVolume; - m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_CLUB_4); - m_sQueueSample.m_nReleasingVolumeModificator = 3; - m_sQueueSample.m_nReleasingVolumeDivider = 3; - m_sQueueSample.m_fSpeedMultiplier = 2.0f; - break; - case SCRIPT_SOUND_PARTY_4_LOOP_L: - m_sQueueSample.m_fSoundIntensity = 80.0f; - m_sQueueSample.m_nSampleIndex = SFX_CLUB_4; - m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; - emittingVolume = maxVolume; - m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_CLUB_4); - m_sQueueSample.m_nReleasingVolumeModificator = 3; - m_sQueueSample.m_nReleasingVolumeDivider = 3; - m_sQueueSample.m_fSpeedMultiplier = 2.0f; - break; - case SCRIPT_SOUND_PARTY_5_LOOP_S: - m_sQueueSample.m_fSoundIntensity = 30.0f; - m_sQueueSample.m_nSampleIndex = SFX_CLUB_5; - m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; - emittingVolume = maxVolume; - m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_CLUB_5); - m_sQueueSample.m_nReleasingVolumeModificator = 3; - m_sQueueSample.m_nReleasingVolumeDivider = 3; - m_sQueueSample.m_fSpeedMultiplier = 2.0f; - break; - case SCRIPT_SOUND_PARTY_5_LOOP_L: - m_sQueueSample.m_fSoundIntensity = 80.0f; - m_sQueueSample.m_nSampleIndex = SFX_CLUB_5; - m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; - emittingVolume = maxVolume; - m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_CLUB_5); - m_sQueueSample.m_nReleasingVolumeModificator = 3; - m_sQueueSample.m_nReleasingVolumeDivider = 3; - m_sQueueSample.m_fSpeedMultiplier = 2.0f; - break; - case SCRIPT_SOUND_PARTY_6_LOOP_S: - m_sQueueSample.m_fSoundIntensity = 30.0f; - m_sQueueSample.m_nSampleIndex = SFX_CLUB_6; - m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; - emittingVolume = maxVolume; - m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_CLUB_6); - m_sQueueSample.m_nReleasingVolumeModificator = 3; - m_sQueueSample.m_nReleasingVolumeDivider = 3; - m_sQueueSample.m_fSpeedMultiplier = 2.0f; - break; - case SCRIPT_SOUND_PARTY_6_LOOP_L: - m_sQueueSample.m_fSoundIntensity = 80.0f; - m_sQueueSample.m_nSampleIndex = SFX_CLUB_6; - m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; - emittingVolume = maxVolume; - m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_CLUB_6); - m_sQueueSample.m_nReleasingVolumeModificator = 3; - m_sQueueSample.m_nReleasingVolumeDivider = 3; - m_sQueueSample.m_fSpeedMultiplier = 2.0f; - break; - case SCRIPT_SOUND_PARTY_7_LOOP_S: - m_sQueueSample.m_fSoundIntensity = 30.0f; - m_sQueueSample.m_nSampleIndex = SFX_CLUB_7; - m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; - emittingVolume = maxVolume; - m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_CLUB_7); - m_sQueueSample.m_nReleasingVolumeModificator = 3; - m_sQueueSample.m_nReleasingVolumeDivider = 3; - m_sQueueSample.m_fSpeedMultiplier = 2.0f; - break; - case SCRIPT_SOUND_PARTY_7_LOOP_L: - m_sQueueSample.m_fSoundIntensity = 80.0f; - m_sQueueSample.m_nSampleIndex = SFX_CLUB_7; - m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; - emittingVolume = maxVolume; - m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_CLUB_7); - m_sQueueSample.m_nReleasingVolumeModificator = 3; - m_sQueueSample.m_nReleasingVolumeDivider = 3; - m_sQueueSample.m_fSpeedMultiplier = 2.0f; - break; - case SCRIPT_SOUND_PARTY_8_LOOP_S: - m_sQueueSample.m_fSoundIntensity = 30.0f; - m_sQueueSample.m_nSampleIndex = SFX_CLUB_8; - m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; - emittingVolume = maxVolume; - m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_CLUB_8); - m_sQueueSample.m_nReleasingVolumeModificator = 3; - m_sQueueSample.m_nReleasingVolumeDivider = 3; - m_sQueueSample.m_fSpeedMultiplier = 2.0f; - break; - case SCRIPT_SOUND_PARTY_8_LOOP_L: - m_sQueueSample.m_fSoundIntensity = 80.0f; - m_sQueueSample.m_nSampleIndex = SFX_CLUB_8; - m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; - emittingVolume = maxVolume; - m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_CLUB_8); - m_sQueueSample.m_nReleasingVolumeModificator = 3; - m_sQueueSample.m_nReleasingVolumeDivider = 3; - m_sQueueSample.m_fSpeedMultiplier = 2.0f; - break; - case SCRIPT_SOUND_PARTY_9_LOOP_S: - m_sQueueSample.m_fSoundIntensity = 30.0f; - m_sQueueSample.m_nSampleIndex = SFX_CLUB_9; - m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; - emittingVolume = maxVolume; - m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_CLUB_9); - m_sQueueSample.m_nReleasingVolumeModificator = 3; - m_sQueueSample.m_nReleasingVolumeDivider = 3; - m_sQueueSample.m_fSpeedMultiplier = 2.0f; - break; - case SCRIPT_SOUND_PARTY_9_LOOP_L: - m_sQueueSample.m_fSoundIntensity = 80.0f; - m_sQueueSample.m_nSampleIndex = SFX_CLUB_9; - m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; - emittingVolume = maxVolume; - m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_CLUB_9); - m_sQueueSample.m_nReleasingVolumeModificator = 3; - m_sQueueSample.m_nReleasingVolumeDivider = 3; - m_sQueueSample.m_fSpeedMultiplier = 2.0f; - break; - case SCRIPT_SOUND_PARTY_10_LOOP_S: - m_sQueueSample.m_fSoundIntensity = 30.0f; - m_sQueueSample.m_nSampleIndex = SFX_CLUB_10; - m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; - emittingVolume = maxVolume; - m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_CLUB_10); - m_sQueueSample.m_nReleasingVolumeModificator = 3; - m_sQueueSample.m_nReleasingVolumeDivider = 3; - m_sQueueSample.m_fSpeedMultiplier = 2.0f; - break; - case SCRIPT_SOUND_PARTY_10_LOOP_L: - m_sQueueSample.m_fSoundIntensity = 80.0f; - m_sQueueSample.m_nSampleIndex = SFX_CLUB_10; - m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; - emittingVolume = maxVolume; - m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_CLUB_10); - m_sQueueSample.m_nReleasingVolumeModificator = 3; - m_sQueueSample.m_nReleasingVolumeDivider = 3; - m_sQueueSample.m_fSpeedMultiplier = 2.0f; - break; - case SCRIPT_SOUND_PARTY_11_LOOP_S: - m_sQueueSample.m_fSoundIntensity = 30.0f; - m_sQueueSample.m_nSampleIndex = SFX_CLUB_11; - m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; - emittingVolume = maxVolume; - m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_CLUB_11); - m_sQueueSample.m_nReleasingVolumeModificator = 3; - m_sQueueSample.m_nReleasingVolumeDivider = 3; - m_sQueueSample.m_fSpeedMultiplier = 2.0f; - break; - case SCRIPT_SOUND_PARTY_11_LOOP_L: - m_sQueueSample.m_fSoundIntensity = 80.0f; - m_sQueueSample.m_nSampleIndex = SFX_CLUB_11; - m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; - emittingVolume = maxVolume; - m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_CLUB_11); - m_sQueueSample.m_nReleasingVolumeModificator = 3; - m_sQueueSample.m_nReleasingVolumeDivider = 3; - m_sQueueSample.m_fSpeedMultiplier = 2.0f; - break; - case SCRIPT_SOUND_PARTY_12_LOOP_S: - m_sQueueSample.m_fSoundIntensity = 30.0f; - m_sQueueSample.m_nSampleIndex = SFX_CLUB_12; - m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; - emittingVolume = maxVolume; - m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_CLUB_12); - m_sQueueSample.m_nReleasingVolumeModificator = 3; - m_sQueueSample.m_nReleasingVolumeDivider = 3; - m_sQueueSample.m_fSpeedMultiplier = 2.0f; - break; - case SCRIPT_SOUND_PARTY_12_LOOP_L: - m_sQueueSample.m_fSoundIntensity = 80.0f; - m_sQueueSample.m_nSampleIndex = SFX_CLUB_12; - m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; - emittingVolume = maxVolume; - m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_CLUB_12); - m_sQueueSample.m_nReleasingVolumeModificator = 3; - m_sQueueSample.m_nReleasingVolumeDivider = 3; - m_sQueueSample.m_fSpeedMultiplier = 2.0f; - break; - case SCRIPT_SOUND_PARTY_13_LOOP_S: - m_sQueueSample.m_fSoundIntensity = 30.0f; - m_sQueueSample.m_nSampleIndex = SFX_CLUB_RAGGA; - m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; - emittingVolume = maxVolume; - m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_CLUB_RAGGA); - m_sQueueSample.m_nReleasingVolumeModificator = 3; - m_sQueueSample.m_nReleasingVolumeDivider = 3; - m_sQueueSample.m_fSpeedMultiplier = 2.0f; - break; - case SCRIPT_SOUND_PARTY_13_LOOP_L: - m_sQueueSample.m_fSoundIntensity = 80.0f; - m_sQueueSample.m_nSampleIndex = SFX_CLUB_RAGGA; - m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; - emittingVolume = maxVolume; - m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_CLUB_RAGGA); - m_sQueueSample.m_nReleasingVolumeModificator = 3; - m_sQueueSample.m_nReleasingVolumeDivider = 3; - m_sQueueSample.m_fSpeedMultiplier = 2.0f; - break; - case SCRIPT_SOUND_STRIP_CLUB_LOOP_1_S: - m_sQueueSample.m_fSoundIntensity = 30.0f; - m_sQueueSample.m_nSampleIndex = SFX_STRIP_CLUB_1; - m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; - emittingVolume = maxVolume; - m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_STRIP_CLUB_1); - m_sQueueSample.m_nReleasingVolumeModificator = 3; - m_sQueueSample.m_nReleasingVolumeDivider = 3; - m_sQueueSample.m_fSpeedMultiplier = 2.0f; - break; - case SCRIPT_SOUND_STRIP_CLUB_LOOP_1_L: - m_sQueueSample.m_fSoundIntensity = 80.0f; - m_sQueueSample.m_nSampleIndex = SFX_STRIP_CLUB_1; - m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; - emittingVolume = maxVolume; - m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_STRIP_CLUB_1); - m_sQueueSample.m_nReleasingVolumeModificator = 3; - m_sQueueSample.m_nReleasingVolumeDivider = 3; - m_sQueueSample.m_fSpeedMultiplier = 2.0f; - break; - case SCRIPT_SOUND_STRIP_CLUB_LOOP_2_S: - m_sQueueSample.m_fSoundIntensity = 30.0f; - m_sQueueSample.m_nSampleIndex = SFX_STRIP_CLUB_2; - m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; - emittingVolume = maxVolume; - m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_STRIP_CLUB_2); - m_sQueueSample.m_nReleasingVolumeModificator = 3; - m_sQueueSample.m_nReleasingVolumeDivider = 3; - m_sQueueSample.m_fSpeedMultiplier = 2.0f; - break; - case SCRIPT_SOUND_STRIP_CLUB_LOOP_2_L: - m_sQueueSample.m_fSoundIntensity = 80.0f; - m_sQueueSample.m_nSampleIndex = SFX_STRIP_CLUB_2; - m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; - emittingVolume = maxVolume; - m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_STRIP_CLUB_2); - m_sQueueSample.m_nReleasingVolumeModificator = 3; - m_sQueueSample.m_nReleasingVolumeDivider = 3; - m_sQueueSample.m_fSpeedMultiplier = 2.0f; - break; - case SCRIPT_SOUND_WORK_SHOP_LOOP_S: - case SCRIPT_SOUND_WORK_SHOP_LOOP_L: - ProcessWorkShopScriptObject(sound); - return; - case SCRIPT_SOUND_SAWMILL_LOOP_S: - case SCRIPT_SOUND_SAWMILL_LOOP_L: - ProcessSawMillScriptObject(sound); - return; - case SCRIPT_SOUND_38: - m_sQueueSample.m_fSoundIntensity = 30.0f; - m_sQueueSample.m_nSampleIndex = SFX_DOG_FOOD_FACTORY; - m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; - emittingVolume = 110; - m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_DOG_FOOD_FACTORY); - m_sQueueSample.m_nReleasingVolumeModificator = 6; - m_sQueueSample.m_nReleasingVolumeDivider = 3; - m_sQueueSample.m_fSpeedMultiplier = 2.0f; - break; - case SCRIPT_SOUND_39: - m_sQueueSample.m_fSoundIntensity = 80.0f; - m_sQueueSample.m_nSampleIndex = SFX_DOG_FOOD_FACTORY; - m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; - emittingVolume = 110; - m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_DOG_FOOD_FACTORY); - m_sQueueSample.m_nReleasingVolumeModificator = 6; - m_sQueueSample.m_nReleasingVolumeDivider = 3; - m_sQueueSample.m_fSpeedMultiplier = 2.0f; - break; - case SCRIPT_SOUND_LAUNDERETTE_LOOP_S: - case SCRIPT_SOUND_LAUNDERETTE_LOOP_L: - ProcessLaunderetteScriptObject(sound); - return; - case SCRIPT_SOUND_CHINATOWN_RESTAURANT_S: - m_sQueueSample.m_fSoundIntensity = 30.0f; - m_sQueueSample.m_nSampleIndex = SFX_RESTAURANT_CHINATOWN; - m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; - emittingVolume = 110; - m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_RESTAURANT_CHINATOWN); - m_sQueueSample.m_nReleasingVolumeModificator = 3; - m_sQueueSample.m_nReleasingVolumeDivider = 3; - m_sQueueSample.m_fSpeedMultiplier = 2.0f; - break; - case SCRIPT_SOUND_CHINATOWN_RESTAURANT_L: - m_sQueueSample.m_fSoundIntensity = 80.0f; - m_sQueueSample.m_nSampleIndex = SFX_RESTAURANT_CHINATOWN; - m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; - emittingVolume = 110; - m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_RESTAURANT_CHINATOWN); - m_sQueueSample.m_nReleasingVolumeModificator = 3; - m_sQueueSample.m_nReleasingVolumeDivider = 3; - m_sQueueSample.m_fSpeedMultiplier = 2.0f; - break; - case SCRIPT_SOUND_CIPRIANI_RESAURANT_S: - m_sQueueSample.m_fSoundIntensity = 30.0f; - m_sQueueSample.m_nSampleIndex = SFX_RESTAURANT_ITALY; - m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; - emittingVolume = 110; - m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_RESTAURANT_ITALY); - m_sQueueSample.m_nReleasingVolumeModificator = 3; - m_sQueueSample.m_nReleasingVolumeDivider = 3; - m_sQueueSample.m_fSpeedMultiplier = 2.0f; - break; - case SCRIPT_SOUND_CIPRIANI_RESAURANT_L: - m_sQueueSample.m_fSoundIntensity = 80.0f; - m_sQueueSample.m_nSampleIndex = SFX_RESTAURANT_ITALY; - m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; - emittingVolume = 110; - m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_RESTAURANT_ITALY); - m_sQueueSample.m_nReleasingVolumeModificator = 3; - m_sQueueSample.m_nReleasingVolumeDivider = 3; - m_sQueueSample.m_fSpeedMultiplier = 2.0f; - break; - case SCRIPT_SOUND_46_S: - m_sQueueSample.m_fSoundIntensity = 30.0f; - m_sQueueSample.m_nSampleIndex = SFX_RESTAURANT_GENERIC_1; - m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; - emittingVolume = 110; - m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_RESTAURANT_GENERIC_1); - m_sQueueSample.m_nReleasingVolumeModificator = 3; - m_sQueueSample.m_nReleasingVolumeDivider = 3; - m_sQueueSample.m_fSpeedMultiplier = 2.0f; - break; - case SCRIPT_SOUND_47_L: - m_sQueueSample.m_fSoundIntensity = 80.0f; - m_sQueueSample.m_nSampleIndex = SFX_RESTAURANT_GENERIC_1; - m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; - emittingVolume = 110; - m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_RESTAURANT_GENERIC_1); - m_sQueueSample.m_nReleasingVolumeModificator = 3; - m_sQueueSample.m_nReleasingVolumeDivider = 3; - m_sQueueSample.m_fSpeedMultiplier = 2.0f; - break; - case SCRIPT_SOUND_MARCO_BISTRO_S: - m_sQueueSample.m_fSoundIntensity = 30.0f; - m_sQueueSample.m_nSampleIndex = SFX_RESTAURANT_GENERIC_2; - m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; - emittingVolume = 110; - m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_RESTAURANT_GENERIC_2); - m_sQueueSample.m_nReleasingVolumeModificator = 3; - m_sQueueSample.m_nReleasingVolumeDivider = 3; - m_sQueueSample.m_fSpeedMultiplier = 2.0f; - break; - case SCRIPT_SOUND_MARCO_BISTRO_L: - m_sQueueSample.m_fSoundIntensity = 80.0f; - m_sQueueSample.m_nSampleIndex = SFX_RESTAURANT_GENERIC_2; - m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; - emittingVolume = 110; - m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_RESTAURANT_GENERIC_2); - m_sQueueSample.m_nReleasingVolumeModificator = 3; - m_sQueueSample.m_nReleasingVolumeDivider = 3; - m_sQueueSample.m_fSpeedMultiplier = 2.0f; - break; - case SCRIPT_SOUND_AIRPORT_LOOP_S: - case SCRIPT_SOUND_AIRPORT_LOOP_L: - ProcessAirportScriptObject(sound); - return; - case SCRIPT_SOUND_SHOP_LOOP_S: - case SCRIPT_SOUND_SHOP_LOOP_L: - ProcessShopScriptObject(sound); - return; - case SCRIPT_SOUND_CINEMA_LOOP_S: - case SCRIPT_SOUND_CINEMA_LOOP_L: - ProcessCinemaScriptObject(sound); - return; - case SCRIPT_SOUND_DOCKS_LOOP_S: - case SCRIPT_SOUND_DOCKS_LOOP_L: - ProcessDocksScriptObject(sound); - return; - case SCRIPT_SOUND_HOME_LOOP_S: - case SCRIPT_SOUND_HOME_LOOP_L: - ProcessHomeScriptObject(sound); - return; - case SCRIPT_SOUND_FRANKIE_PIANO: - m_sQueueSample.m_fSoundIntensity = 30.0f; - m_sQueueSample.m_nSampleIndex = SFX_PIANO_BAR_1; - m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; - emittingVolume = maxVolume; - m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_PIANO_BAR_1); - m_sQueueSample.m_nReleasingVolumeModificator = 3; - m_sQueueSample.m_nReleasingVolumeDivider = 3; - m_sQueueSample.m_fSpeedMultiplier = 2.0f; - break; - case SCRIPT_SOUND_PARTY_1_LOOP: - m_sQueueSample.m_fSoundIntensity = 80.0f; - m_sQueueSample.m_nSampleIndex = SFX_CLUB_1; - m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; - emittingVolume = maxVolume; - m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_CLUB_1); - m_sQueueSample.m_nReleasingVolumeModificator = 3; - m_sQueueSample.m_nReleasingVolumeDivider = 3; - m_sQueueSample.m_fSpeedMultiplier = 2.0f; - break; - case SCRIPT_SOUND_PORN_CINEMA_1_S: - case SCRIPT_SOUND_PORN_CINEMA_1_L: - case SCRIPT_SOUND_PORN_CINEMA_2_S: - case SCRIPT_SOUND_PORN_CINEMA_2_L: - case SCRIPT_SOUND_PORN_CINEMA_3_S: - case SCRIPT_SOUND_PORN_CINEMA_3_L: - case SCRIPT_SOUND_MISTY_SEX_S: - case SCRIPT_SOUND_MISTY_SEX_L: - ProcessPornCinema(sound); - return; - case SCRIPT_SOUND_BANK_ALARM_LOOP_S: - m_sQueueSample.m_fSoundIntensity = 30.0f; - m_sQueueSample.m_nSampleIndex = SFX_BANK_ALARM_1; - m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; - emittingVolume = 90; - m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_BANK_ALARM_1); - m_sQueueSample.m_nReleasingVolumeModificator = 2; - m_sQueueSample.m_nReleasingVolumeDivider = 3; - m_sQueueSample.m_fSpeedMultiplier = 2.0f; - break; - case SCRIPT_SOUND_BANK_ALARM_LOOP_L: - m_sQueueSample.m_fSoundIntensity = 80.0f; - m_sQueueSample.m_nSampleIndex = SFX_BANK_ALARM_1; - m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; - emittingVolume = 90; - m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_BANK_ALARM_1); - m_sQueueSample.m_nReleasingVolumeModificator = 2; - m_sQueueSample.m_nReleasingVolumeDivider = 3; - m_sQueueSample.m_fSpeedMultiplier = 2.0f; - break; - case SCRIPT_SOUND_POLICE_BALL_LOOP_S: - m_sQueueSample.m_fSoundIntensity = 30.0f; - m_sQueueSample.m_nSampleIndex = SFX_POLICE_BALL_1; - m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; - emittingVolume = maxVolume; - m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_POLICE_BALL_1); - m_sQueueSample.m_nReleasingVolumeModificator = 2; - m_sQueueSample.m_nReleasingVolumeDivider = 3; - m_sQueueSample.m_fSpeedMultiplier = 2.0f; - break; - case SCRIPT_SOUND_POLICE_BALL_LOOP_L: - m_sQueueSample.m_fSoundIntensity = 80.0f; - m_sQueueSample.m_nSampleIndex = SFX_POLICE_BALL_1; - m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; - emittingVolume = maxVolume; - m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_POLICE_BALL_1); - m_sQueueSample.m_nReleasingVolumeModificator = 2; - m_sQueueSample.m_nReleasingVolumeDivider = 3; - m_sQueueSample.m_fSpeedMultiplier = 2.0f; - break; - case SCRIPT_SOUND_RAVE_LOOP_INDUSTRIAL_S: - m_sQueueSample.m_fSoundIntensity = 30.0f; - m_sQueueSample.m_nSampleIndex = SFX_RAVE_INDUSTRIAL; - m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; - emittingVolume = maxVolume; - m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_RAVE_INDUSTRIAL); - m_sQueueSample.m_nReleasingVolumeModificator = 3; - m_sQueueSample.m_nReleasingVolumeDivider = 3; - m_sQueueSample.m_fSpeedMultiplier = 2.0f; - break; - case SCRIPT_SOUND_RAVE_LOOP_INDUSTRIAL_L: - m_sQueueSample.m_fSoundIntensity = 80.0f; - m_sQueueSample.m_nSampleIndex = SFX_RAVE_INDUSTRIAL; - m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; - emittingVolume = maxVolume; - m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_RAVE_INDUSTRIAL); - m_sQueueSample.m_nReleasingVolumeModificator = 3; - m_sQueueSample.m_nReleasingVolumeDivider = 3; - m_sQueueSample.m_fSpeedMultiplier = 2.0f; - break; - case SCRIPT_SOUND_POLICE_CELL_BEATING_LOOP_S: - case SCRIPT_SOUND_POLICE_CELL_BEATING_LOOP_L: - ProcessPoliceCellBeatingScriptObject(sound); - return; - case SCRIPT_SOUND_RAVE_1_LOOP_S: - case SCRIPT_SOUND_RAVE_2_LOOP_S: - m_sQueueSample.m_fSoundIntensity = 30.0f; - m_sQueueSample.m_nSampleIndex = SFX_RAVE_COMMERCIAL; - m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; - emittingVolume = maxVolume; - m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(m_sQueueSample.m_nSampleIndex); - m_sQueueSample.m_nReleasingVolumeModificator = 3; - m_sQueueSample.m_nReleasingVolumeDivider = 3; - m_sQueueSample.m_fSpeedMultiplier = 2.0f; - break; - case SCRIPT_SOUND_RAVE_1_LOOP_L: - case SCRIPT_SOUND_RAVE_2_LOOP_L: - m_sQueueSample.m_fSoundIntensity = 80.0f; - m_sQueueSample.m_nSampleIndex = SFX_RAVE_COMMERCIAL; - m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; - emittingVolume = maxVolume; - m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(m_sQueueSample.m_nSampleIndex); - m_sQueueSample.m_nReleasingVolumeModificator = 3; - m_sQueueSample.m_nReleasingVolumeDivider = 3; - m_sQueueSample.m_fSpeedMultiplier = 2.0f; - break; - case SCRIPT_SOUND_RAVE_3_LOOP_S: - m_sQueueSample.m_fSoundIntensity = 30.0f; - m_sQueueSample.m_nSampleIndex = SFX_RAVE_SUBURBAN; - m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; - emittingVolume = maxVolume; - m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_RAVE_SUBURBAN); - m_sQueueSample.m_nReleasingVolumeModificator = 3; - m_sQueueSample.m_nReleasingVolumeDivider = 3; - m_sQueueSample.m_fSpeedMultiplier = 2.0f; - break; - case SCRIPT_SOUND_RAVE_3_LOOP_L: - m_sQueueSample.m_fSoundIntensity = 80.0f; - m_sQueueSample.m_nSampleIndex = SFX_RAVE_SUBURBAN; - m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; - emittingVolume = maxVolume; - m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_RAVE_SUBURBAN); - m_sQueueSample.m_nReleasingVolumeModificator = 3; - m_sQueueSample.m_nReleasingVolumeDivider = 3; - m_sQueueSample.m_fSpeedMultiplier = 2.0f; - break; - case SCRIPT_SOUND_PRETEND_FIRE_LOOP: - m_sQueueSample.m_fSoundIntensity = 50.0f; - m_sQueueSample.m_nSampleIndex = SFX_CAR_ON_FIRE; - m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; - emittingVolume = 80; - m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_CAR_ON_FIRE); - m_sQueueSample.m_nReleasingVolumeModificator = 8; - m_sQueueSample.m_nReleasingVolumeDivider = 10; - m_sQueueSample.m_fSpeedMultiplier = 2.0f; - break; - default: - return; - } - - distSquared = GetDistanceSquared(m_sQueueSample.m_vecPos); - if (distSquared < SQR(m_sQueueSample.m_fSoundIntensity)) { - m_sQueueSample.m_fDistance = Sqrt(distSquared); - m_sQueueSample.m_nVolume = ComputeVolume(emittingVolume, m_sQueueSample.m_fSoundIntensity, m_sQueueSample.m_fDistance); - if (m_sQueueSample.m_nVolume) { - m_sQueueSample.m_nCounter = 0; - m_sQueueSample.m_bIs2D = false; - m_sQueueSample.m_nLoopCount = 0; - m_sQueueSample.m_bReleasingSoundFlag = false; - m_sQueueSample.m_bReverbFlag = true; - m_sQueueSample.m_nEmittingVolume = emittingVolume; - m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex); - m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex); - m_sQueueSample.m_bRequireReflection = false; - AddSampleToRequestedQueue(); - } - } -} - -void -cAudioManager::ProcessMissionAudio() -{ - float dist; - uint8 emittingVol; - uint8 pan; - float distSquared; - CVector vec; - - static uint8 nCheckPlayingDelay = 0; - static uint8 nFramesUntilFailedLoad = 0; - static uint8 nFramesForPretendPlaying = 0; - - if (m_bIsInitialised) { - if (m_sMissionAudio.m_nSampleIndex != NO_SAMPLE) { - switch (m_sMissionAudio.m_nLoadingStatus) { - case LOADING_STATUS_NOT_LOADED: - SampleManager.PreloadStreamedFile(m_sMissionAudio.m_nSampleIndex, 1); - m_sMissionAudio.m_nLoadingStatus = LOADING_STATUS_LOADED; - nFramesUntilFailedLoad = 0; - return; - case LOADING_STATUS_LOADED: - if (!m_sMissionAudio.m_bIsPlayed) - return; - if (g_bMissionAudioLoadFailed) { - if (m_bTimerJustReset) { - ClearMissionAudio(); - SampleManager.StopStreamedFile(1); - nFramesForPretendPlaying = 0; - nCheckPlayingDelay = 0; - nFramesUntilFailedLoad = 0; - } else if (!m_nUserPause) { - if (++nFramesForPretendPlaying < 120) { - m_sMissionAudio.m_nPlayStatus = PLAY_STATUS_PLAYING; - } else { - m_sMissionAudio.m_nPlayStatus = PLAY_STATUS_FINISHED; - m_sMissionAudio.m_nSampleIndex = NO_SAMPLE; - } - } - } else { - if (m_sMissionAudio.m_nPlayStatus) { - if (m_sMissionAudio.m_nPlayStatus != PLAY_STATUS_PLAYING) - return; - if (m_bTimerJustReset) { - ClearMissionAudio(); - SampleManager.StopStreamedFile(1); - return; - } - if (MissionScriptAudioUsesPoliceChannel(m_sMissionAudio.m_nSampleIndex)) { - if (!m_nUserPause) { - if (nCheckPlayingDelay) { - --nCheckPlayingDelay; - } else if (GetMissionScriptPoliceAudioPlayingStatus() == PLAY_STATUS_FINISHED || - m_sMissionAudio.m_nMissionAudioCounter-- == 0) { - m_sMissionAudio.m_nPlayStatus = PLAY_STATUS_FINISHED; - m_sMissionAudio.m_nSampleIndex = NO_SAMPLE; - SampleManager.StopStreamedFile(1); - m_sMissionAudio.m_nMissionAudioCounter = 0; - } - } - } else if (m_sMissionAudio.field_22) { - if (SampleManager.IsStreamPlaying(1) || m_nUserPause || m_nPreviousUserPause) { - if (m_nUserPause) - SampleManager.PauseStream(1, 1); - else - SampleManager.PauseStream(0, 1); - } else { - m_sMissionAudio.m_nPlayStatus = PLAY_STATUS_FINISHED; - m_sMissionAudio.m_nSampleIndex = NO_SAMPLE; - SampleManager.StopStreamedFile(1); - m_sMissionAudio.m_nMissionAudioCounter = 0; - } - } else { - if (m_nUserPause) - return; - if (nCheckPlayingDelay--) { - if (!SampleManager.IsStreamPlaying(1)) - return; - nCheckPlayingDelay = 0; - } - m_sMissionAudio.field_22 = 1; - } - } else { - if (MissionScriptAudioUsesPoliceChannel(m_sMissionAudio.m_nSampleIndex)) { - SetMissionScriptPoliceAudio(m_sMissionAudio.m_nSampleIndex); - } else { - if (m_nUserPause) - SampleManager.PauseStream(1, 1); - if (m_sMissionAudio.m_bPredefinedProperties) { - SampleManager.SetStreamedVolumeAndPan(80, 63, 1, 1); - } else { - distSquared = GetDistanceSquared(m_sMissionAudio.m_vecPos); - if (distSquared >= 2500.f) { - emittingVol = 0; - pan = 63; - } else { - dist = Sqrt(distSquared); - emittingVol = ComputeVolume(80, 50.0f, dist); - TranslateEntity(&m_sMissionAudio.m_vecPos, &vec); - pan = ComputePan(50.f, &vec); - } - SampleManager.SetStreamedVolumeAndPan(emittingVol, pan, 1, 1); - } - SampleManager.StartPreloadedStreamedFile(1); - } - m_sMissionAudio.m_nPlayStatus = PLAY_STATUS_PLAYING; - nCheckPlayingDelay = 30; - } - } - break; - case 2: - if (++nFramesUntilFailedLoad >= 90) { - nFramesForPretendPlaying = 0; - g_bMissionAudioLoadFailed = true; - nFramesUntilFailedLoad = 0; - m_sMissionAudio.m_nLoadingStatus = LOADING_STATUS_LOADED; - } - return; - default: - return; - } - } - } -} - -void -cAudioManager::ProcessModelCarEngine(cVehicleParams *params) -{ - CAutomobile *automobile; - float allowedVelocity; - int32 emittingVol; - float velocityChange; - - if (params->m_fDistance < 900.f) { - automobile = (CAutomobile *)params->m_pVehicle; - if (automobile->bEngineOn) { - if (automobile->m_nWheelsOnGround) { - velocityChange = Abs(params->m_fVelocityChange); - } else { - if (automobile->m_nDriveWheelsOnGround) - automobile->m_fGasPedalAudio = automobile->m_fGasPedalAudio * 0.4f; - velocityChange = automobile->m_fGasPedalAudio * params->m_pTransmission->fMaxVelocity; - } - if (velocityChange > 0.001f) { - allowedVelocity = 0.5f * params->m_pTransmission->fMaxVelocity; - if (velocityChange < allowedVelocity) - emittingVol = (90.f * velocityChange / allowedVelocity); - else - emittingVol = 90; - if (emittingVol) { - CalculateDistance(params->m_bDistanceCalculated, params->m_fDistance); - m_sQueueSample.m_nVolume = ComputeVolume(emittingVol, 30.f, m_sQueueSample.m_fDistance); - if (m_sQueueSample.m_nVolume) { - m_sQueueSample.m_nCounter = 2; - m_sQueueSample.m_nSampleIndex = SFX_REMOTE_CONTROLLED_CAR; - m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; - m_sQueueSample.m_bIs2D = false; - m_sQueueSample.m_nReleasingVolumeModificator = 1; - m_sQueueSample.m_nFrequency = (11025.f * velocityChange / params->m_pTransmission->fMaxVelocity + 11025.f); - m_sQueueSample.m_nLoopCount = 0; - m_sQueueSample.m_nEmittingVolume = emittingVol; - m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex); - m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex); - m_sQueueSample.m_fSpeedMultiplier = 3.0f; - m_sQueueSample.m_fSoundIntensity = 30.0f; - m_sQueueSample.m_bReleasingSoundFlag = false; - m_sQueueSample.m_nReleasingVolumeDivider = 3; - m_sQueueSample.m_bReverbFlag = true; - m_sQueueSample.m_bRequireReflection = false; - AddSampleToRequestedQueue(); - } - } - } - } - } -} - -void -cAudioManager::ProcessOneShotScriptObject(uint8 sound) -{ - CPlayerPed *playerPed; - uint8 emittingVolume; - float distSquared; - - cPedParams male; - cPedParams female; - - static uint8 iSound = 0; - - switch (sound) { - case SCRIPT_SOUND_INJURED_PED_MALE_OUCH_S: - case SCRIPT_SOUND_INJURED_PED_MALE_OUCH_L: - male.m_pPed = nil; - male.m_bDistanceCalculated = false; - male.m_fDistance = GetDistanceSquared(m_sQueueSample.m_vecPos); - SetupPedComments(&male, SOUND_INJURED_PED_MALE_OUCH); - return; - case SCRIPT_SOUND_INJURED_PED_FEMALE_OUCH_S: - case SCRIPT_SOUND_INJURED_PED_FEMALE_OUCH_L: - female.m_pPed = nil; - female.m_bDistanceCalculated = false; - female.m_fDistance = GetDistanceSquared(m_sQueueSample.m_vecPos); - SetupPedComments(&female, SOUND_INJURED_PED_FEMALE); - return; - case SCRIPT_SOUND_GATE_START_CLUNK: - case SCRIPT_SOUND_GATE_STOP_CLUNK: - m_sQueueSample.m_fSoundIntensity = 40.0f; - m_sQueueSample.m_nSampleIndex = SFX_COL_GATE; - m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; - if (sound == SCRIPT_SOUND_GATE_START_CLUNK) - m_sQueueSample.m_nFrequency = 10600; - else - m_sQueueSample.m_nFrequency = 9000; - m_sQueueSample.m_nReleasingVolumeModificator = 1; - m_sQueueSample.m_fSpeedMultiplier = 0.0f; - m_sQueueSample.m_bIs2D = false; - m_sQueueSample.m_bRequireReflection = true; - emittingVolume = RandomDisplacement(10) + 50; - break; - case SCRIPT_SOUND_BULLET_HIT_GROUND_1: - case SCRIPT_SOUND_BULLET_HIT_GROUND_2: - case SCRIPT_SOUND_BULLET_HIT_GROUND_3: - m_sQueueSample.m_fSoundIntensity = 50.0f; - m_sQueueSample.m_nSampleIndex = m_anRandomTable[iSound % 5] % 3 + SFX_BULLET_WALL_1; - m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; - m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(m_sQueueSample.m_nSampleIndex); - m_sQueueSample.m_nFrequency += RandomDisplacement(m_sQueueSample.m_nFrequency / 32); - m_sQueueSample.m_nReleasingVolumeModificator = 9; - m_sQueueSample.m_fSpeedMultiplier = 0.0f; - m_sQueueSample.m_bIs2D = false; - emittingVolume = m_anRandomTable[2] % 20 + 90; - break; - case SCRIPT_SOUND_110: - case SCRIPT_SOUND_111: - if (SampleManager.IsSampleBankLoaded(0) != 1) - return; - m_sQueueSample.m_fSoundIntensity = 80.0f; - m_sQueueSample.m_nSampleIndex = SFX_TRAIN_STATION_ANNOUNCE; - m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; - emittingVolume = maxVolume; - m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_TRAIN_STATION_ANNOUNCE); - m_sQueueSample.m_nReleasingVolumeModificator = 0; - m_sQueueSample.m_fSpeedMultiplier = 2.0f; - m_sQueueSample.m_bIs2D = false; - break; - case SCRIPT_SOUND_PAYPHONE_RINGING: - m_sQueueSample.m_fSoundIntensity = 80.0f; - m_sQueueSample.m_nSampleIndex = SFX_PHONE_RING; - m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; - emittingVolume = 80; - m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_PHONE_RING); - m_sQueueSample.m_nReleasingVolumeModificator = 1; - m_sQueueSample.m_fSpeedMultiplier = 2.0f; - m_sQueueSample.m_bIs2D = false; - m_sQueueSample.m_bRequireReflection = false; - break; - case SCRIPT_SOUND_GLASS_BREAK_L: - m_sQueueSample.m_fSoundIntensity = 60.0f; - m_sQueueSample.m_nSampleIndex = SFX_GLASS_SMASH; - m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; - emittingVolume = 70; - m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_GLASS_SMASH); - m_sQueueSample.m_nReleasingVolumeModificator = 3; - m_sQueueSample.m_fSpeedMultiplier = 0.0f; - m_sQueueSample.m_bIs2D = false; - break; - case SCRIPT_SOUND_GLASS_BREAK_S: - m_sQueueSample.m_fSoundIntensity = 60.0f; - m_sQueueSample.m_nSampleIndex = SFX_GLASS_SMASH; - m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; - emittingVolume = 60; - m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_GLASS_SMASH); - m_sQueueSample.m_nReleasingVolumeModificator = 3; - m_sQueueSample.m_fSpeedMultiplier = 0.0f; - m_sQueueSample.m_bIs2D = false; - break; - case SCRIPT_SOUND_GLASS_CRACK: - m_sQueueSample.m_fSoundIntensity = 60.0f; - m_sQueueSample.m_nSampleIndex = SFX_GLASS_CRACK; - m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; - emittingVolume = 70; - m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_GLASS_CRACK); - m_sQueueSample.m_nReleasingVolumeModificator = 3; - m_sQueueSample.m_fSpeedMultiplier = 0.0f; - m_sQueueSample.m_bIs2D = false; - m_sQueueSample.m_bRequireReflection = true; - break; - case SCRIPT_SOUND_GLASS_LIGHT_BREAK: - m_sQueueSample.m_fSoundIntensity = 55.0f; - m_sQueueSample.m_nSampleIndex = (m_anRandomTable[4] & 3) + SFX_GLASS_SHARD_1; - m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; - m_sQueueSample.m_nFrequency = RandomDisplacement(2000) + 19000; - m_sQueueSample.m_nReleasingVolumeModificator = 9; - m_sQueueSample.m_fSpeedMultiplier = 0.0f; - m_sQueueSample.m_bIs2D = false; - emittingVolume = RandomDisplacement(11) + 25; - break; - case SCRIPT_SOUND_BOX_DESTROYED_1: - m_sQueueSample.m_fSoundIntensity = 60.0f; - m_sQueueSample.m_nSampleIndex = SFX_WOODEN_BOX_SMASH; - m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; - m_sQueueSample.m_nFrequency = RandomDisplacement(1500) + 18600; - m_sQueueSample.m_nReleasingVolumeModificator = 3; - m_sQueueSample.m_fSpeedMultiplier = 0.0f; - m_sQueueSample.m_bIs2D = false; - m_sQueueSample.m_bRequireReflection = true; - emittingVolume = m_anRandomTable[2] % 20 + 80; - break; - case SCRIPT_SOUND_BOX_DESTROYED_2: - m_sQueueSample.m_fSoundIntensity = 60.0f; - m_sQueueSample.m_nSampleIndex = SFX_CARDBOARD_BOX_SMASH; - m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; - m_sQueueSample.m_nFrequency = RandomDisplacement(1500) + 18600; - m_sQueueSample.m_nReleasingVolumeModificator = 3; - m_sQueueSample.m_fSpeedMultiplier = 0.0f; - m_sQueueSample.m_bIs2D = false; - m_sQueueSample.m_bRequireReflection = true; - emittingVolume = m_anRandomTable[2] % 20 + 80; - break; - case SCRIPT_SOUND_METAL_COLLISION: - m_sQueueSample.m_fSoundIntensity = 60.0f; - m_sQueueSample.m_nSampleIndex = m_anRandomTable[3] % 5 + SFX_COL_CAR_1; - m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; - m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(m_sQueueSample.m_nSampleIndex); - m_sQueueSample.m_nFrequency += RandomDisplacement(m_sQueueSample.m_nFrequency / 16); - m_sQueueSample.m_nReleasingVolumeModificator = 3; - m_sQueueSample.m_fSpeedMultiplier = 0.0f; - m_sQueueSample.m_bIs2D = false; - m_sQueueSample.m_bRequireReflection = true; - emittingVolume = m_anRandomTable[2] % 30 + 70; - break; - case SCRIPT_SOUND_TIRE_COLLISION: - m_sQueueSample.m_fSoundIntensity = 60.0f; - m_sQueueSample.m_nSampleIndex = SFX_TYRE_BUMP; - m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; - m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(m_sQueueSample.m_nSampleIndex); - m_sQueueSample.m_nFrequency += RandomDisplacement(m_sQueueSample.m_nFrequency / 16); - m_sQueueSample.m_nReleasingVolumeModificator = 3; - m_sQueueSample.m_fSpeedMultiplier = 0.0f; - m_sQueueSample.m_bIs2D = false; - m_sQueueSample.m_bRequireReflection = true; - emittingVolume = m_anRandomTable[2] % 30 + 60; - break; - case SCRIPT_SOUND_GUNSHELL_DROP: - playerPed = FindPlayerPed(); - if (playerPed) { - switch (playerPed->m_nSurfaceTouched) { - case SURFACE_GRASS: - case SURFACE_DIRT: - case SURFACE_DIRTTRACK: - case SURFACE_SCAFFOLD: - case SURFACE_FLESH: - case SURFACE_SAND: - case SURFACE_TIRE: - case SURFACE_HEDGE: - m_sQueueSample.m_nSampleIndex = SFX_BULLET_SHELL_HIT_GROUND_2; - m_sQueueSample.m_nFrequency = RandomDisplacement(500) + 11000; - m_sQueueSample.m_nReleasingVolumeModificator = 18; - m_sQueueSample.m_fSoundIntensity = 20.0f; - m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; - m_sQueueSample.m_fSpeedMultiplier = 0.0f; - m_sQueueSample.m_bIs2D = false; - emittingVolume = m_anRandomTable[2] % 20 + 30; - distSquared = GetDistanceSquared(m_sQueueSample.m_vecPos); - if (distSquared < SQR(m_sQueueSample.m_fSoundIntensity)) { - m_sQueueSample.m_fDistance = Sqrt(distSquared); - m_sQueueSample.m_nVolume = ComputeVolume(emittingVolume, m_sQueueSample.m_fSoundIntensity, m_sQueueSample.m_fDistance); - if (m_sQueueSample.m_nVolume) { - m_sQueueSample.m_nCounter = iSound++; - m_sQueueSample.m_nLoopCount = 1; - m_sQueueSample.m_bReleasingSoundFlag = true; - m_sQueueSample.m_nEmittingVolume = emittingVolume; - m_sQueueSample.m_nLoopStart = 0; - m_sQueueSample.m_nLoopEnd = -1; - m_sQueueSample.m_bReverbFlag = true; - AddSampleToRequestedQueue(); - } - } - return; - case SURFACE_PUDDLE: - return; - default: - break; - } - } - m_sQueueSample.m_nSampleIndex = SFX_BULLET_SHELL_HIT_GROUND_1; - m_sQueueSample.m_nFrequency = RandomDisplacement(750) + 18000; - m_sQueueSample.m_nReleasingVolumeModificator = 15; - m_sQueueSample.m_fSoundIntensity = 20.0f; - m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; - m_sQueueSample.m_fSpeedMultiplier = 0.0f; - m_sQueueSample.m_bIs2D = false; - emittingVolume = m_anRandomTable[2] % 20 + 30; - break; - case SCRIPT_SOUND_GUNSHELL_DROP_SOFT: - m_sQueueSample.m_nSampleIndex = SFX_BULLET_SHELL_HIT_GROUND_2; - m_sQueueSample.m_nFrequency = RandomDisplacement(500) + 11000; - m_sQueueSample.m_nReleasingVolumeModificator = 18; - m_sQueueSample.m_fSoundIntensity = 20.0f; - m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; - m_sQueueSample.m_fSpeedMultiplier = 0.0f; - m_sQueueSample.m_bIs2D = false; - emittingVolume = m_anRandomTable[2] % 20 + 30; - break; - default: - return; - } - - distSquared = GetDistanceSquared(m_sQueueSample.m_vecPos); - if (distSquared < SQR(m_sQueueSample.m_fSoundIntensity)) { - m_sQueueSample.m_fDistance = Sqrt(distSquared); - m_sQueueSample.m_nVolume = ComputeVolume(emittingVolume, m_sQueueSample.m_fSoundIntensity, m_sQueueSample.m_fDistance); - if (m_sQueueSample.m_nVolume) { - m_sQueueSample.m_nCounter = iSound++; - m_sQueueSample.m_nLoopCount = 1; - m_sQueueSample.m_bReleasingSoundFlag = true; - m_sQueueSample.m_nEmittingVolume = emittingVolume; - m_sQueueSample.m_nLoopStart = 0; - m_sQueueSample.m_nLoopEnd = -1; - m_sQueueSample.m_bReverbFlag = true; - AddSampleToRequestedQueue(); - } - } -} - -void -cAudioManager::ProcessPed(CPhysical *ped) -{ - cPedParams params; - - params.m_pPed = nil; - params.m_bDistanceCalculated = false; - params.m_fDistance = 0.0f; - - m_sQueueSample.m_vecPos = ped->GetPosition(); - - // params.m_bDistanceCalculated = false; - params.m_pPed = (CPed *)ped; - params.m_fDistance = GetDistanceSquared(m_sQueueSample.m_vecPos); -// TODO(MIAMI): just making this compile -// if (ped->GetModelIndex() == MI_FATMALE02) -// ProcessPedHeadphones(¶ms); - ProcessPedOneShots(¶ms); -} - -void -cAudioManager::ProcessPedHeadphones(cPedParams *params) -{ - CPed *ped; - CAutomobile *veh; - uint8 emittingVol; - - if (params->m_fDistance < 49.f) { - ped = params->m_pPed; - if (!ped->bIsAimingGun || ped->m_bodyPartBleeding != PED_HEAD) { - CalculateDistance(params->m_bDistanceCalculated, params->m_fDistance); - if (ped->bInVehicle && ped->m_nPedState == PED_DRIVING) { - emittingVol = 10; - veh = (CAutomobile *)ped->m_pMyVehicle; - if (veh && veh->IsCar()) { - for (int32 i = 2; i < ARRAY_SIZE(veh->Doors); i++) { - if (!veh->IsDoorClosed((eDoors)i) || veh->IsDoorMissing((eDoors)i)) { - emittingVol = 42; - break; - } - } - } - } else { - emittingVol = 42; - } - - m_sQueueSample.m_nVolume = ComputeVolume(emittingVol, 7.f, m_sQueueSample.m_fDistance); - if (m_sQueueSample.m_nVolume) { - m_sQueueSample.m_nCounter = 64; - m_sQueueSample.m_nSampleIndex = SFX_HEADPHONES; - m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; - m_sQueueSample.m_bIs2D = false; - m_sQueueSample.m_nReleasingVolumeModificator = 5; - m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_HEADPHONES); - m_sQueueSample.m_nLoopCount = 0; - m_sQueueSample.m_nEmittingVolume = emittingVol; - m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex); - m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex); - m_sQueueSample.m_fSpeedMultiplier = 4.0f; - m_sQueueSample.m_fSoundIntensity = 7.0f; - m_sQueueSample.m_bReleasingSoundFlag = false; - m_sQueueSample.m_nReleasingVolumeDivider = 5; - m_sQueueSample.m_bReverbFlag = true; - m_sQueueSample.m_bRequireReflection = false; - AddSampleToRequestedQueue(); - } - return; - } - } -} - -void -cAudioManager::ProcessPedOneShots(cPedParams *params) -{ - uint8 emittingVol; - int32 sampleIndex; - - CPed *ped = params->m_pPed; - - bool stereo; - int16 sound; - bool noReflection; - CWeapon *weapon; - float maxDist = 0.f; // uninitialized variable - - static uint8 iSound = 21; - - weapon = params->m_pPed->GetWeapon(); - for (uint32 i = 0; i < m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_AudioEvents; i++) { - noReflection = false; - stereo = false; - m_sQueueSample.m_bRequireReflection = false; - sound = m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_awAudioEvent[i]; - switch (sound) { - case SOUND_STEP_START: - case SOUND_STEP_END: - if (!params->m_pPed->bIsLooking) { - emittingVol = m_anRandomTable[3] % 15 + 45; - if (FindPlayerPed() != m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_pEntity) - emittingVol /= 2; - maxDist = 400.f; - switch (params->m_pPed->m_nSurfaceTouched) { - case SURFACE_GRASS: - sampleIndex = m_anRandomTable[1] % 5 + SFX_FOOTSTEP_GRASS_1; - break; - case SURFACE_DIRT: - case SURFACE_DIRTTRACK: - sampleIndex = m_anRandomTable[4] % 5 + SFX_FOOTSTEP_GRAVEL_1; - break; - case SURFACE_METAL6: - case SURFACE_METAL_DOOR: - case SURFACE_BILLBOARD: - case SURFACE_STEEL: - case SURFACE_METAL_POLE: - case SURFACE_STREET_LIGHT: - case SURFACE_METAL14: - case SURFACE_METAL15: - case SURFACE_METAL_FENCE: - case SURFACE_METAL27: - case SURFACE_METAL28: - sampleIndex = m_anRandomTable[0] % 5 + SFX_FOOTSTEP_METAL_1; - break; - case SURFACE_SAND: - sampleIndex = (m_anRandomTable[4] & 3) + SFX_FOOTSTEP_SAND_1; - break; - case SURFACE_PUDDLE: - sampleIndex = (m_anRandomTable[3] & 3) + SFX_FOOTSTEP_WATER_1; - break; - case SURFACE_WOOD: - case SURFACE_WOOD_BOX: - case SURFACE_WOOD_PLANK: - sampleIndex = m_anRandomTable[2] % 5 + SFX_FOOTSTEP_WOOD_1; - break; - case SURFACE_HEDGE: - sampleIndex = m_anRandomTable[2] % 5 + SFX_COL_VEG_1; - break; - default: - sampleIndex = m_anRandomTable[2] % 5 + SFX_FOOTSTEP_CONCRETE_1; - break; - } - m_sQueueSample.m_nSampleIndex = sampleIndex; - m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; - m_sQueueSample.m_nCounter = m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_awAudioEvent[i] - 28; - m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(m_sQueueSample.m_nSampleIndex); - m_sQueueSample.m_nFrequency += RandomDisplacement(m_sQueueSample.m_nFrequency / 17); - switch (params->m_pPed->m_nMoveState) { - case PEDMOVE_WALK: - emittingVol /= 4; - m_sQueueSample.m_nFrequency = 9 * m_sQueueSample.m_nFrequency / 10; - break; - case PEDMOVE_RUN: - emittingVol /= 2; - m_sQueueSample.m_nFrequency = 11 * m_sQueueSample.m_nFrequency / 10; - break; - case PEDMOVE_SPRINT: - m_sQueueSample.m_nFrequency = 12 * m_sQueueSample.m_nFrequency / 10; - break; - default: - break; - } - m_sQueueSample.m_nReleasingVolumeModificator = 5; - m_sQueueSample.m_fSpeedMultiplier = 0.0f; - m_sQueueSample.m_fSoundIntensity = 20.0f; - m_sQueueSample.m_nLoopCount = 1; - m_sQueueSample.m_nLoopStart = 0; - m_sQueueSample.m_nLoopEnd = -1; - m_sQueueSample.m_nEmittingVolume = emittingVol; - m_sQueueSample.m_bIs2D = false; - m_sQueueSample.m_bReleasingSoundFlag = true; - m_sQueueSample.m_bRequireReflection = true; - } - break; - case SOUND_FALL_LAND: - case SOUND_FALL_COLLAPSE: - if (!ped->bIsLooking) { - maxDist = SQR(30); - emittingVol = m_anRandomTable[3] % 20 + 80; - if (ped->m_nSurfaceTouched == SURFACE_PUDDLE) { - m_sQueueSample.m_nSampleIndex = (m_anRandomTable[3] & 3) + SFX_FOOTSTEP_WATER_1; - } else if (sound == SOUND_FALL_LAND) { - m_sQueueSample.m_nSampleIndex = SFX_BODY_LAND; - } else { - m_sQueueSample.m_nSampleIndex = SFX_BODY_LAND_AND_FALL; - } - m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; - m_sQueueSample.m_nCounter = 1; - m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(m_sQueueSample.m_nSampleIndex); - m_sQueueSample.m_nFrequency += RandomDisplacement(m_sQueueSample.m_nFrequency / 17); - m_sQueueSample.m_nReleasingVolumeModificator = 2; - m_sQueueSample.m_fSpeedMultiplier = 0.0f; - m_sQueueSample.m_fSoundIntensity = 30.0f; - m_sQueueSample.m_nLoopCount = 1; - m_sQueueSample.m_nLoopStart = 0; - m_sQueueSample.m_nLoopEnd = -1; - m_sQueueSample.m_nEmittingVolume = emittingVol; - m_sQueueSample.m_bIs2D = false; - m_sQueueSample.m_bReleasingSoundFlag = true; - m_sQueueSample.m_bRequireReflection = true; - } - break; - case SOUND_FIGHT_PUNCH_33: - m_sQueueSample.m_nSampleIndex = SFX_FIGHT_1; - m_sQueueSample.m_nFrequency = 18000; - m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; - m_sQueueSample.m_nCounter = iSound; - stereo = true; - ++iSound; - m_sQueueSample.m_nReleasingVolumeModificator = 3; - m_sQueueSample.m_fSpeedMultiplier = 0.0f; - m_sQueueSample.m_fSoundIntensity = 30.0f; - maxDist = SQR(30); - m_sQueueSample.m_nLoopCount = 1; - m_sQueueSample.m_nLoopStart = 0; - emittingVol = m_anRandomTable[3] % 26 + 100; - m_sQueueSample.m_nLoopEnd = -1; - m_sQueueSample.m_nEmittingVolume = emittingVol; - m_sQueueSample.m_bIs2D = false; - m_sQueueSample.m_bReleasingSoundFlag = true; - m_sQueueSample.m_bRequireReflection = true; - break; - case SOUND_FIGHT_KICK_34: - m_sQueueSample.m_nSampleIndex = SFX_FIGHT_1; - m_sQueueSample.m_nFrequency = 16500; - m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; - m_sQueueSample.m_nCounter = iSound; - stereo = true; - ++iSound; - m_sQueueSample.m_nReleasingVolumeModificator = 3; - m_sQueueSample.m_fSpeedMultiplier = 0.0f; - m_sQueueSample.m_fSoundIntensity = 30.0f; - maxDist = SQR(30); - m_sQueueSample.m_nLoopCount = 1; - m_sQueueSample.m_nLoopStart = 0; - emittingVol = m_anRandomTable[3] % 26 + 100; - m_sQueueSample.m_nLoopEnd = -1; - m_sQueueSample.m_nEmittingVolume = emittingVol; - m_sQueueSample.m_bIs2D = false; - m_sQueueSample.m_bReleasingSoundFlag = true; - m_sQueueSample.m_bRequireReflection = true; - break; - case SOUND_FIGHT_HEADBUTT_35: - m_sQueueSample.m_nSampleIndex = SFX_FIGHT_1; - m_sQueueSample.m_nFrequency = 20000; - m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; - m_sQueueSample.m_nCounter = iSound; - stereo = true; - ++iSound; - m_sQueueSample.m_nReleasingVolumeModificator = 3; - m_sQueueSample.m_fSpeedMultiplier = 0.0f; - m_sQueueSample.m_fSoundIntensity = 30.0f; - maxDist = SQR(30); - m_sQueueSample.m_nLoopCount = 1; - m_sQueueSample.m_nLoopStart = 0; - emittingVol = m_anRandomTable[3] % 26 + 100; - m_sQueueSample.m_nLoopEnd = -1; - m_sQueueSample.m_nEmittingVolume = emittingVol; - m_sQueueSample.m_bIs2D = false; - m_sQueueSample.m_bReleasingSoundFlag = true; - m_sQueueSample.m_bRequireReflection = true; - break; - case SOUND_FIGHT_PUNCH_36: - m_sQueueSample.m_nSampleIndex = SFX_FIGHT_2; - m_sQueueSample.m_nFrequency = 18000; - m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; - m_sQueueSample.m_nCounter = iSound; - stereo = true; - ++iSound; - m_sQueueSample.m_nReleasingVolumeModificator = 3; - m_sQueueSample.m_fSpeedMultiplier = 0.0f; - m_sQueueSample.m_fSoundIntensity = 30.0f; - maxDist = SQR(30); - m_sQueueSample.m_nLoopCount = 1; - m_sQueueSample.m_nLoopStart = 0; - emittingVol = m_anRandomTable[3] % 26 + 100; - m_sQueueSample.m_nLoopEnd = -1; - m_sQueueSample.m_nEmittingVolume = emittingVol; - m_sQueueSample.m_bIs2D = false; - m_sQueueSample.m_bReleasingSoundFlag = true; - m_sQueueSample.m_bRequireReflection = true; - break; - case SOUND_FIGHT_PUNCH_37: - m_sQueueSample.m_nSampleIndex = SFX_FIGHT_2; - m_sQueueSample.m_nFrequency = 16500; - m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; - m_sQueueSample.m_nCounter = iSound; - stereo = true; - ++iSound; - m_sQueueSample.m_nReleasingVolumeModificator = 3; - m_sQueueSample.m_fSpeedMultiplier = 0.0f; - m_sQueueSample.m_fSoundIntensity = 30.0f; - maxDist = SQR(30); - m_sQueueSample.m_nLoopCount = 1; - m_sQueueSample.m_nLoopStart = 0; - emittingVol = m_anRandomTable[3] % 26 + 100; - m_sQueueSample.m_nLoopEnd = -1; - m_sQueueSample.m_nEmittingVolume = emittingVol; - m_sQueueSample.m_bIs2D = false; - m_sQueueSample.m_bReleasingSoundFlag = true; - m_sQueueSample.m_bRequireReflection = true; - break; - case SOUND_FIGHT_CLOSE_PUNCH_38: - m_sQueueSample.m_nSampleIndex = SFX_FIGHT_2; - m_sQueueSample.m_nFrequency = 20000; - m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; - m_sQueueSample.m_nCounter = iSound; - stereo = true; - ++iSound; - m_sQueueSample.m_nReleasingVolumeModificator = 3; - m_sQueueSample.m_fSpeedMultiplier = 0.0f; - m_sQueueSample.m_fSoundIntensity = 30.0f; - maxDist = SQR(30); - m_sQueueSample.m_nLoopCount = 1; - m_sQueueSample.m_nLoopStart = 0; - emittingVol = m_anRandomTable[3] % 26 + 100; - m_sQueueSample.m_nLoopEnd = -1; - m_sQueueSample.m_nEmittingVolume = emittingVol; - m_sQueueSample.m_bIs2D = false; - m_sQueueSample.m_bReleasingSoundFlag = true; - m_sQueueSample.m_bRequireReflection = true; - break; - case SOUND_FIGHT_PUNCH_39: - m_sQueueSample.m_nSampleIndex = SFX_FIGHT_4; - m_sQueueSample.m_nFrequency = 18000; - m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; - m_sQueueSample.m_nCounter = iSound; - stereo = true; - ++iSound; - m_sQueueSample.m_nReleasingVolumeModificator = 3; - m_sQueueSample.m_fSpeedMultiplier = 0.0f; - m_sQueueSample.m_fSoundIntensity = 30.0f; - maxDist = SQR(30); - m_sQueueSample.m_nLoopCount = 1; - m_sQueueSample.m_nLoopStart = 0; - emittingVol = m_anRandomTable[3] % 26 + 100; - m_sQueueSample.m_nLoopEnd = -1; - m_sQueueSample.m_nEmittingVolume = emittingVol; - m_sQueueSample.m_bIs2D = false; - m_sQueueSample.m_bReleasingSoundFlag = true; - m_sQueueSample.m_bRequireReflection = true; - break; - case SOUND_FIGHT_PUNCH_OR_KICK_BELOW_40: - m_sQueueSample.m_nSampleIndex = SFX_FIGHT_4; - m_sQueueSample.m_nFrequency = 16500; - m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; - m_sQueueSample.m_nCounter = iSound; - stereo = true; - ++iSound; - m_sQueueSample.m_nReleasingVolumeModificator = 3; - m_sQueueSample.m_fSpeedMultiplier = 0.0f; - m_sQueueSample.m_fSoundIntensity = 30.0f; - maxDist = SQR(30); - m_sQueueSample.m_nLoopCount = 1; - m_sQueueSample.m_nLoopStart = 0; - emittingVol = m_anRandomTable[3] % 26 + 100; - m_sQueueSample.m_nLoopEnd = -1; - m_sQueueSample.m_nEmittingVolume = emittingVol; - m_sQueueSample.m_bIs2D = false; - m_sQueueSample.m_bReleasingSoundFlag = true; - m_sQueueSample.m_bRequireReflection = true; - break; - case SOUND_FIGHT_PUNCH_41: - m_sQueueSample.m_nSampleIndex = SFX_FIGHT_4; - m_sQueueSample.m_nFrequency = 20000; - m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; - m_sQueueSample.m_nCounter = iSound; - stereo = true; - ++iSound; - m_sQueueSample.m_nReleasingVolumeModificator = 3; - m_sQueueSample.m_fSpeedMultiplier = 0.0f; - m_sQueueSample.m_fSoundIntensity = 30.0f; - maxDist = SQR(30); - m_sQueueSample.m_nLoopCount = 1; - m_sQueueSample.m_nLoopStart = 0; - emittingVol = m_anRandomTable[3] % 26 + 100; - m_sQueueSample.m_nLoopEnd = -1; - m_sQueueSample.m_nEmittingVolume = emittingVol; - m_sQueueSample.m_bIs2D = false; - m_sQueueSample.m_bReleasingSoundFlag = true; - m_sQueueSample.m_bRequireReflection = true; - break; - case SOUND_FIGHT_PUNCH_FROM_BEHIND_42: - m_sQueueSample.m_nSampleIndex = SFX_FIGHT_5; - m_sQueueSample.m_nFrequency = 18000; - m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; - m_sQueueSample.m_nCounter = iSound; - stereo = true; - ++iSound; - m_sQueueSample.m_nReleasingVolumeModificator = 3; - m_sQueueSample.m_fSpeedMultiplier = 0.0f; - m_sQueueSample.m_fSoundIntensity = 30.0f; - maxDist = SQR(30); - m_sQueueSample.m_nLoopCount = 1; - m_sQueueSample.m_nLoopStart = 0; - emittingVol = m_anRandomTable[3] % 26 + 100; - m_sQueueSample.m_nLoopEnd = -1; - m_sQueueSample.m_nEmittingVolume = emittingVol; - m_sQueueSample.m_bIs2D = false; - m_sQueueSample.m_bReleasingSoundFlag = true; - m_sQueueSample.m_bRequireReflection = true; - break; - case SOUND_FIGHT_KNEE_OR_KICK_43: - m_sQueueSample.m_nSampleIndex = SFX_FIGHT_5; - m_sQueueSample.m_nFrequency = 16500; - m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; - m_sQueueSample.m_nCounter = iSound; - stereo = true; - ++iSound; - m_sQueueSample.m_nReleasingVolumeModificator = 3; - m_sQueueSample.m_fSpeedMultiplier = 0.0f; - m_sQueueSample.m_fSoundIntensity = 30.0f; - maxDist = SQR(30); - m_sQueueSample.m_nLoopCount = 1; - m_sQueueSample.m_nLoopStart = 0; - emittingVol = m_anRandomTable[3] % 26 + 100; - m_sQueueSample.m_nLoopEnd = -1; - m_sQueueSample.m_nEmittingVolume = emittingVol; - m_sQueueSample.m_bIs2D = false; - m_sQueueSample.m_bReleasingSoundFlag = true; - m_sQueueSample.m_bRequireReflection = true; - break; - case SOUND_FIGHT_KICK_44: - m_sQueueSample.m_nSampleIndex = SFX_FIGHT_5; - m_sQueueSample.m_nFrequency = 20000; - m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; - m_sQueueSample.m_nCounter = iSound; - stereo = true; - ++iSound; - m_sQueueSample.m_nReleasingVolumeModificator = 3; - m_sQueueSample.m_fSpeedMultiplier = 0.0f; - m_sQueueSample.m_fSoundIntensity = 30.0f; - maxDist = SQR(30); - m_sQueueSample.m_nLoopCount = 1; - m_sQueueSample.m_nLoopStart = 0; - emittingVol = m_anRandomTable[3] % 26 + 100; - m_sQueueSample.m_nLoopEnd = -1; - m_sQueueSample.m_nEmittingVolume = emittingVol; - m_sQueueSample.m_bIs2D = false; - m_sQueueSample.m_bReleasingSoundFlag = true; - m_sQueueSample.m_bRequireReflection = true; - break; - case SOUND_WEAPON_BAT_ATTACK: - m_sQueueSample.m_nSampleIndex = SFX_BAT_HIT_LEFT; - m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; - m_sQueueSample.m_nCounter = iSound++; - stereo = true; - m_sQueueSample.m_nFrequency = RandomDisplacement(2000) + 22000; - m_sQueueSample.m_nReleasingVolumeModificator = 3; - m_sQueueSample.m_fSpeedMultiplier = 0.0f; - m_sQueueSample.m_fSoundIntensity = 30.0f; - maxDist = SQR(30); - m_sQueueSample.m_nLoopCount = 1; - m_sQueueSample.m_nLoopStart = 0; - m_sQueueSample.m_nLoopEnd = -1; - emittingVol = m_anRandomTable[2] % 20 + 100; - m_sQueueSample.m_nEmittingVolume = emittingVol; - m_sQueueSample.m_bIs2D = false; - m_sQueueSample.m_bReleasingSoundFlag = true; - if (m_bDynamicAcousticModelingStatus) - m_sQueueSample.m_bRequireReflection = true; - else - noReflection = true; - break; - case SOUND_WEAPON_SHOT_FIRED: - weapon = &ped->m_weapons[ped->m_currentWeapon]; - switch (weapon->m_eWeaponType) { - case WEAPONTYPE_COLT45: - m_sQueueSample.m_nSampleIndex = SFX_COLT45_LEFT; - m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; - m_sQueueSample.m_nCounter = iSound++; - stereo = true; - m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_COLT45_LEFT); - m_sQueueSample.m_nFrequency += RandomDisplacement(m_sQueueSample.m_nFrequency / 32); - m_sQueueSample.m_nReleasingVolumeModificator = 3; - m_sQueueSample.m_fSpeedMultiplier = 0.0f; - m_sQueueSample.m_fSoundIntensity = 50.0f; - maxDist = SQR(50); - m_sQueueSample.m_nLoopCount = 1; - m_sQueueSample.m_nLoopStart = 0; - m_sQueueSample.m_nLoopEnd = -1; - emittingVol = m_anRandomTable[1] % 10 + 90; - m_sQueueSample.m_nEmittingVolume = emittingVol; - m_sQueueSample.m_bIs2D = false; - m_sQueueSample.m_bReleasingSoundFlag = true; - if (m_bDynamicAcousticModelingStatus) - m_sQueueSample.m_bRequireReflection = true; - else - noReflection = true; - break; - case WEAPONTYPE_UZI: - m_sQueueSample.m_nSampleIndex = SFX_UZI_LEFT; - m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; - m_sQueueSample.m_nCounter = iSound++; - stereo = true; - m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_UZI_LEFT); - m_sQueueSample.m_nFrequency += RandomDisplacement(m_sQueueSample.m_nFrequency / 32); - m_sQueueSample.m_nReleasingVolumeModificator = 3; - m_sQueueSample.m_fSpeedMultiplier = 0.0f; - m_sQueueSample.m_fSoundIntensity = 80.0f; - maxDist = SQR(80); - m_sQueueSample.m_nLoopCount = 1; - m_sQueueSample.m_nLoopStart = 0; - emittingVol = m_anRandomTable[3] % 15 + 70; - m_sQueueSample.m_nLoopEnd = -1; - m_sQueueSample.m_nEmittingVolume = emittingVol; - m_sQueueSample.m_bIs2D = false; - m_sQueueSample.m_bReleasingSoundFlag = true; - break; - case WEAPONTYPE_SHOTGUN: - m_sQueueSample.m_nSampleIndex = SFX_SHOTGUN_LEFT; - m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; - m_sQueueSample.m_nCounter = iSound++; - stereo = true; - m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_SHOTGUN_LEFT); - m_sQueueSample.m_nFrequency += RandomDisplacement(m_sQueueSample.m_nFrequency / 32); - m_sQueueSample.m_nReleasingVolumeModificator = 3; - m_sQueueSample.m_fSpeedMultiplier = 0.0f; - m_sQueueSample.m_fSoundIntensity = 60.0f; - maxDist = 3600.f; - m_sQueueSample.m_nLoopCount = 1; - m_sQueueSample.m_nLoopStart = 0; - m_sQueueSample.m_nLoopEnd = -1; - emittingVol = m_anRandomTable[2] % 10 + 100; - m_sQueueSample.m_nEmittingVolume = emittingVol; - m_sQueueSample.m_bIs2D = false; - m_sQueueSample.m_bReleasingSoundFlag = true; - if (m_bDynamicAcousticModelingStatus) - m_sQueueSample.m_bRequireReflection = true; - else - noReflection = true; - break; - case WEAPONTYPE_AK47: - m_sQueueSample.m_nSampleIndex = SFX_AK47_LEFT; - m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; - m_sQueueSample.m_nCounter = iSound++; - stereo = true; - m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_AK47_LEFT); - m_sQueueSample.m_nFrequency += RandomDisplacement(m_sQueueSample.m_nFrequency / 32); - m_sQueueSample.m_nReleasingVolumeModificator = 3; - m_sQueueSample.m_fSpeedMultiplier = 0.0f; - m_sQueueSample.m_fSoundIntensity = 80.0f; - maxDist = SQR(80); - m_sQueueSample.m_nLoopCount = 1; - m_sQueueSample.m_nLoopStart = 0; - emittingVol = m_anRandomTable[1] % 15 + 70; - m_sQueueSample.m_nLoopEnd = -1; - m_sQueueSample.m_nEmittingVolume = emittingVol; - m_sQueueSample.m_bIs2D = false; - m_sQueueSample.m_bReleasingSoundFlag = true; - break; - case WEAPONTYPE_M16: - m_sQueueSample.m_nSampleIndex = SFX_M16_LEFT; - m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; - m_sQueueSample.m_nCounter = iSound++; - stereo = true; - m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_M16_LEFT); - m_sQueueSample.m_nFrequency += RandomDisplacement(m_sQueueSample.m_nFrequency / 32); - m_sQueueSample.m_nReleasingVolumeModificator = 3; - m_sQueueSample.m_fSpeedMultiplier = 0.0f; - m_sQueueSample.m_fSoundIntensity = 80.0f; - maxDist = SQR(80); - m_sQueueSample.m_nLoopCount = 1; - m_sQueueSample.m_nLoopStart = 0; - emittingVol = m_anRandomTable[4] % 15 + 70; - m_sQueueSample.m_nLoopEnd = -1; - m_sQueueSample.m_nEmittingVolume = emittingVol; - m_sQueueSample.m_bIs2D = false; - m_sQueueSample.m_bReleasingSoundFlag = true; - break; - case WEAPONTYPE_SNIPERRIFLE: - m_sQueueSample.m_nSampleIndex = SFX_SNIPER_LEFT; - m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; - m_sQueueSample.m_nCounter = iSound++; - stereo = true; - m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_SNIPER_LEFT); - m_sQueueSample.m_nFrequency += RandomDisplacement(m_sQueueSample.m_nFrequency / 32); - m_sQueueSample.m_nReleasingVolumeModificator = 3; - m_sQueueSample.m_fSpeedMultiplier = 0.0f; - m_sQueueSample.m_fSoundIntensity = 60.0f; - maxDist = 3600.f; - m_sQueueSample.m_nLoopCount = 1; - m_sQueueSample.m_nLoopStart = 0; - m_sQueueSample.m_nLoopEnd = -1; - emittingVol = m_anRandomTable[4] % 10 + 110; - m_sQueueSample.m_nEmittingVolume = emittingVol; - m_sQueueSample.m_bIs2D = false; - m_sQueueSample.m_bReleasingSoundFlag = true; - if (m_bDynamicAcousticModelingStatus) - m_sQueueSample.m_bRequireReflection = true; - else - noReflection = true; - break; - case WEAPONTYPE_ROCKETLAUNCHER: - m_sQueueSample.m_nSampleIndex = SFX_ROCKET_LEFT; - m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; - m_sQueueSample.m_nCounter = iSound++; - stereo = true; - m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_ROCKET_LEFT); - m_sQueueSample.m_nFrequency += RandomDisplacement(m_sQueueSample.m_nFrequency / 32); - m_sQueueSample.m_nReleasingVolumeModificator = 1; - m_sQueueSample.m_fSpeedMultiplier = 0.0f; - m_sQueueSample.m_fSoundIntensity = 90.0f; - maxDist = 8100.f; - m_sQueueSample.m_nLoopCount = 1; - m_sQueueSample.m_nLoopStart = 0; - m_sQueueSample.m_nLoopEnd = -1; - emittingVol = m_anRandomTable[0] % 20 + 80; - m_sQueueSample.m_nEmittingVolume = emittingVol; - m_sQueueSample.m_bIs2D = false; - m_sQueueSample.m_bReleasingSoundFlag = true; - if (m_bDynamicAcousticModelingStatus) - m_sQueueSample.m_bRequireReflection = true; - else - noReflection = true; - break; - case WEAPONTYPE_FLAMETHROWER: - m_sQueueSample.m_nSampleIndex = SFX_FLAMETHROWER_LEFT; - m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; - m_sQueueSample.m_nCounter = 9; - emittingVol = 90; - m_sQueueSample.m_nFrequency = (10 * m_sQueueSample.m_nEntityIndex & 2047) + SampleManager.GetSampleBaseFrequency(SFX_FLAMETHROWER_LEFT); - m_sQueueSample.m_nReleasingVolumeModificator = 3; - m_sQueueSample.m_fSpeedMultiplier = 4.0f; - m_sQueueSample.m_fSoundIntensity = 60.0f; - maxDist = 3600.f; - m_sQueueSample.m_nLoopCount = 0; - m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex); - m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex); - m_sQueueSample.m_nEmittingVolume = 90; - m_sQueueSample.m_bIs2D = false; - m_sQueueSample.m_bReleasingSoundFlag = false; - m_sQueueSample.m_nReleasingVolumeDivider = 6; - if (m_bDynamicAcousticModelingStatus) - m_sQueueSample.m_bRequireReflection = true; - else - noReflection = true; - break; - default: - continue; - } - - break; - case SOUND_WEAPON_RELOAD: - weapon = &ped->m_weapons[ped->m_currentWeapon]; - switch (weapon->m_eWeaponType) { - case WEAPONTYPE_COLT45: - m_sQueueSample.m_nSampleIndex = SFX_PISTOL_RELOAD; - m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_PISTOL_RELOAD) + RandomDisplacement(300); - break; - case WEAPONTYPE_UZI: - m_sQueueSample.m_nSampleIndex = SFX_M16_RELOAD; - m_sQueueSample.m_nFrequency = 39243; - break; - case WEAPONTYPE_SHOTGUN: - m_sQueueSample.m_nSampleIndex = SFX_AK47_RELOAD; - m_sQueueSample.m_nFrequency = 30290; - break; - case WEAPONTYPE_AK47: - m_sQueueSample.m_nSampleIndex = SFX_AK47_RELOAD; - m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_AK47_RELOAD); - break; - case WEAPONTYPE_M16: - m_sQueueSample.m_nSampleIndex = SFX_M16_RELOAD; - m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_M16_RELOAD); - break; - case WEAPONTYPE_SNIPERRIFLE: - m_sQueueSample.m_nSampleIndex = SFX_RIFLE_RELOAD; - m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_RIFLE_RELOAD); - break; - case WEAPONTYPE_ROCKETLAUNCHER: - m_sQueueSample.m_nSampleIndex = SFX_ROCKET_RELOAD; - m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_ROCKET_RELOAD); - break; - default: - continue; - } - emittingVol = 75; - m_sQueueSample.m_nCounter = iSound++; - stereo = true; - m_sQueueSample.m_nFrequency += RandomDisplacement(300); - m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; - m_sQueueSample.m_nReleasingVolumeModificator = 5; - m_sQueueSample.m_fSpeedMultiplier = 0.0f; - m_sQueueSample.m_fSoundIntensity = 30.0f; - maxDist = SQR(30); - m_sQueueSample.m_nLoopCount = 1; - m_sQueueSample.m_nLoopStart = 0; - m_sQueueSample.m_nLoopEnd = -1; - m_sQueueSample.m_nEmittingVolume = 75; - m_sQueueSample.m_bIs2D = false; - m_sQueueSample.m_bReleasingSoundFlag = true; - m_sQueueSample.m_bRequireReflection = true; - break; - case SOUND_WEAPON_AK47_BULLET_ECHO: - case SOUND_WEAPON_UZI_BULLET_ECHO: - case SOUND_WEAPON_M16_BULLET_ECHO: - m_sQueueSample.m_nSampleIndex = SFX_UZI_END_LEFT; - m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; - m_sQueueSample.m_nCounter = iSound++; - stereo = true; - m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_UZI_END_LEFT); - m_sQueueSample.m_nFrequency += RandomDisplacement(m_sQueueSample.m_nFrequency / 16); - m_sQueueSample.m_nReleasingVolumeModificator = 3; - m_sQueueSample.m_fSpeedMultiplier = 0.0f; - m_sQueueSample.m_fSoundIntensity = 80.0f; - maxDist = SQR(80); - m_sQueueSample.m_nLoopCount = 1; - m_sQueueSample.m_nLoopStart = 0; - m_sQueueSample.m_nLoopEnd = -1; - emittingVol = m_anRandomTable[4] % 10 + 40; - m_sQueueSample.m_nEmittingVolume = emittingVol; - m_sQueueSample.m_bIs2D = false; - m_sQueueSample.m_bReleasingSoundFlag = true; - if (m_bDynamicAcousticModelingStatus) - m_sQueueSample.m_bRequireReflection = true; - else - noReflection = true; - break; - case SOUND_WEAPON_FLAMETHROWER_FIRE: - m_sQueueSample.m_nSampleIndex = SFX_FLAMETHROWER_START_LEFT; - m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; - m_sQueueSample.m_nCounter = iSound++; - m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_FLAMETHROWER_START_LEFT); - m_sQueueSample.m_nFrequency += RandomDisplacement(m_sQueueSample.m_nFrequency / 16); - m_sQueueSample.m_nReleasingVolumeModificator = 3; - m_sQueueSample.m_fSpeedMultiplier = 4.0f; - m_sQueueSample.m_fSoundIntensity = 60.0f; - maxDist = 3600.f; - m_sQueueSample.m_nLoopCount = 1; - m_sQueueSample.m_nLoopStart = 0; - m_sQueueSample.m_nLoopEnd = -1; - emittingVol = 70; - m_sQueueSample.m_nEmittingVolume = 70; - m_sQueueSample.m_bIs2D = false; - m_sQueueSample.m_bReleasingSoundFlag = true; - break; - case SOUND_WEAPON_HIT_PED: - m_sQueueSample.m_nSampleIndex = SFX_BULLET_PED; - m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; - m_sQueueSample.m_nCounter = iSound++; - stereo = true; - m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_BULLET_PED); - m_sQueueSample.m_nFrequency += RandomDisplacement(m_sQueueSample.m_nFrequency / 8); - m_sQueueSample.m_nReleasingVolumeModificator = 7; - m_sQueueSample.m_fSpeedMultiplier = 0.0f; - m_sQueueSample.m_fSoundIntensity = 30.0f; - maxDist = SQR(30); - m_sQueueSample.m_nLoopCount = 1; - m_sQueueSample.m_nLoopStart = 0; - emittingVol = m_anRandomTable[0] % 20 + 90; - m_sQueueSample.m_nLoopEnd = -1; - m_sQueueSample.m_nEmittingVolume = emittingVol; - m_sQueueSample.m_bIs2D = false; - m_sQueueSample.m_bReleasingSoundFlag = true; - break; - case SOUND_SPLASH: - m_sQueueSample.m_nSampleIndex = SFX_SPLASH_1; - m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; - m_sQueueSample.m_nCounter = iSound++; - stereo = true; - m_sQueueSample.m_nFrequency = RandomDisplacement(1400) + 20000; - m_sQueueSample.m_nReleasingVolumeModificator = 1; - m_sQueueSample.m_fSpeedMultiplier = 0.0f; - m_sQueueSample.m_fSoundIntensity = 40.0f; - maxDist = 1600.f; - m_sQueueSample.m_nLoopCount = 1; - m_sQueueSample.m_nLoopStart = 0; - emittingVol = m_anRandomTable[2] % 30 + 70; - m_sQueueSample.m_nLoopEnd = -1; - m_sQueueSample.m_nEmittingVolume = emittingVol; - m_sQueueSample.m_bIs2D = false; - m_sQueueSample.m_bReleasingSoundFlag = true; - m_sQueueSample.m_bRequireReflection = true; - break; - default: - SetupPedComments(params, sound); - continue; - } - - if (stereo && iSound > 60) - iSound = 21; - if (params->m_fDistance < maxDist) { - CalculateDistance(params->m_bDistanceCalculated, params->m_fDistance); - m_sQueueSample.m_nVolume = ComputeVolume(emittingVol, m_sQueueSample.m_fSoundIntensity, m_sQueueSample.m_fDistance); - if (m_sQueueSample.m_nVolume) { - if (noReflection) { - if (0.2f * m_sQueueSample.m_fSoundIntensity <= m_sQueueSample.m_fDistance) { - noReflection = 0; - } else { - m_sQueueSample.m_bIs2D = true; - m_sQueueSample.m_nOffset = 0; - } - } - m_sQueueSample.m_bReverbFlag = true; - AddSampleToRequestedQueue(); - if (noReflection) { - m_sQueueSample.m_nOffset = 127; - ++m_sQueueSample.m_nSampleIndex; - if (m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_awAudioEvent[i] != SOUND_WEAPON_SHOT_FIRED || - weapon->m_eWeaponType != WEAPONTYPE_FLAMETHROWER) { - m_sQueueSample.m_nCounter = iSound++; - if (iSound > 60) - iSound = 21; - } else { - ++m_sQueueSample.m_nCounter; - } - AddSampleToRequestedQueue(); - } - } - } - } -} - -void -cAudioManager::ProcessPhysical(int32 id) -{ - CPhysical *entity = (CPhysical *)m_asAudioEntities[id].m_pEntity; - if (entity) { - switch (entity->GetType()) { - case ENTITY_TYPE_VEHICLE: - ProcessVehicle((CVehicle *)m_asAudioEntities[id].m_pEntity); - break; - case ENTITY_TYPE_PED: - ProcessPed((CPhysical *)m_asAudioEntities[id].m_pEntity); - break; - default: - return; - } - } -} - -void -cAudioManager::ProcessPlane(cVehicleParams *params) -{ - switch (params->m_nIndex) { - case AIRTRAIN: - ProcessJumbo(params); - break; - case DEADDODO: - ProcessCesna(params); - break; - default: - debug("Plane Model Id is %d\n, ", params->m_pVehicle->GetModelIndex()); - break; - } -} - -struct tVehicleSampleData { - eSfxSample m_nAccelerationSampleIndex; - uint8 m_bEngineSoundType; - eSfxSample m_nHornSample; - int32 m_nHornFrequency; - uint8 m_nSirenOrAlarmSample; - int32 m_nSirenOrAlarmFrequency; - uint8 m_bDoorType; -}; - -// TODO(MIAMI): this is bogus. get the real data in here! -const tVehicleSampleData aVehicleSettings[110] = {{SFX_CAR_REV_2, 2, SFX_CAR_HORN_JEEP, 26513, SFX_CAR_ALARM_1, 9935, 1}, - {SFX_CAR_REV_1, 1, SFX_CAR_HORN_56CHEV, 11487, SFX_CAR_ALARM_1, 9935, 0}, - {SFX_CAR_REV_8, 8, SFX_CAR_HORN_PORSCHE, 11025, SFX_CAR_ALARM_1, 10928, 1}, - {SFX_CAR_REV_6, 6, SFX_CAR_HORN_TRUCK, 29711, SFX_CAR_ALARM_1, 9935, 2}, - {SFX_CAR_REV_1, 1, SFX_CAR_HORN_56CHEV, 12893, SFX_CAR_ALARM_1, 8941, 0}, - {SFX_CAR_REV_5, 5, SFX_CAR_HORN_BMW328, 10706, SFX_CAR_ALARM_1, 11922, 1}, - {SFX_CAR_REV_4, 4, SFX_CAR_HORN_TRUCK, 29711, SFX_CAR_ALARM_1, 7948, 2}, - {SFX_CAR_REV_6, 6, SFX_CAR_HORN_TRUCK, 29711, SFX_POLICE_SIREN_SLOW, 11556, 2}, - {SFX_CAR_REV_6, 6, SFX_CAR_HORN_TRUCK, 31478, SFX_CAR_ALARM_1, 8941, 2}, - {SFX_CAR_REV_1, 1, SFX_CAR_HORN_BMW328, 9538, SFX_CAR_ALARM_1, 12220, 1}, - {SFX_CAR_REV_1, 1, SFX_CAR_HORN_56CHEV, 10842, SFX_CAR_ALARM_1, 9935, 0}, - {SFX_CAR_REV_3, 3, SFX_CAR_HORN_BMW328, 12017, SFX_CAR_ALARM_1, 9935, 1}, - {SFX_CAR_REV_2, 2, SFX_CAR_HORN_JEEP, 22295, SFX_CAR_ALARM_1, 12200, 1}, - {SFX_CAR_REV_4, 4, SFX_CAR_HORN_BUS2, 18000, SFX_CAR_ALARM_1, 13400, 1}, - {SFX_CAR_REV_4, 4, SFX_CAR_HORN_BUS, 18286, SFX_CAR_ALARM_1, 9935, 2}, - {SFX_CAR_REV_3, 3, SFX_CAR_HORN_PORSCHE, 11025, SFX_CAR_ALARM_1, 13600, 1}, - {SFX_CAR_REV_4, 4, SFX_CAR_HORN_JEEP, 22295, SFX_AMBULANCE_SIREN_SLOW, 8795, 2}, - {SFX_CAR_REV_5, 5, SFX_CAR_HORN_PORSCHE, 9271, SFX_POLICE_SIREN_SLOW, 16168, 1}, - {SFX_CAR_REV_1, 1, SFX_CAR_HORN_56CHEV, 12170, SFX_CAR_ALARM_1, 8000, 1}, - {SFX_CAR_REV_1, 1, SFX_CAR_HORN_BUS2, 12345, SFX_CAR_ALARM_1, 9935, 0}, - {SFX_CAR_REV_2, 2, SFX_CAR_HORN_BMW328, 10796, SFX_CAR_ALARM_1, 8543, 1}, - {SFX_CAR_REV_5, 5, SFX_CAR_HORN_PORSCHE, 9271, SFX_CAR_ALARM_1, 9935, 1}, - {SFX_CAR_REV_2, 2, SFX_CAR_HORN_PICKUP, 10924, SFX_CAR_ALARM_1, 9935, 1}, - {SFX_CAR_REV_1, 1, SFX_CAR_HORN_PICKUP, 11025, SFX_ICE_CREAM_TUNE, 11025, 0}, - {SFX_CAR_REV_7, 7, SFX_CAR_HORN_JEEP, 26513, SFX_CAR_ALARM_1, 9935, 1}, - {SFX_CAR_REV_1, 1, SFX_CAR_HORN_JEEP, 26513, SFX_CAR_ALARM_1, 10000, 0}, - {SFX_CAR_REV_5, 5, SFX_CAR_HORN_BMW328, 10706, SFX_POLICE_SIREN_SLOW, 13596, 1}, - {SFX_CAR_REV_4, 4, SFX_CAR_HORN_BUS, 17260, SFX_POLICE_SIREN_SLOW, 13000, 2}, - {SFX_CAR_REV_4, 4, SFX_CAR_HORN_PICKUP, 8670, SFX_CAR_ALARM_1, 9935, 2}, - {SFX_CAR_REV_8, 8, SFX_CAR_HORN_PORSCHE, 10400, SFX_CAR_ALARM_1, 10123, 1}, - {SFX_CAR_REV_1, 1, SFX_CAR_HORN_JEEP, 26513, SFX_POLICE_SIREN_SLOW, 13596, 0}, - {SFX_CAR_REV_6, 6, SFX_CAR_HORN_BUS2, 11652, SFX_CAR_ALARM_1, 10554, 3}, - {SFX_CAR_REV_6, 6, SFX_CAR_HORN_TRUCK, 29711, SFX_CAR_ALARM_1, 8000, 2}, - {SFX_CAR_REV_6, 6, SFX_CAR_HORN_TRUCK, 28043, SFX_CAR_ALARM_1, 9935, 2}, - {SFX_CAR_REV_1, 0, SFX_CAR_HORN_TRUCK, 29711, SFX_CAR_ALARM_1, 9935, 3}, - {SFX_CAR_REV_1, 0, SFX_CAR_HORN_JEEP, 26513, SFX_CAR_ALARM_1, 9935, 0}, - {SFX_CESNA_IDLE, 0, SFX_CAR_HORN_JEEP, 26513, SFX_CAR_ALARM_1, 9935, 0}, - {SFX_CAR_REV_6, 6, SFX_CAR_HORN_BUS, 16291, SFX_CAR_ALARM_1, 7500, 3}, - {SFX_CAR_REV_1, 1, SFX_CAR_HORN_56CHEV, 10842, SFX_CAR_ALARM_1, 9935, 0}, - {SFX_CAR_REV_1, 1, SFX_CAR_HORN_56CHEV, 10233, SFX_CAR_ALARM_1, 8935, 0}, - {SFX_CAR_REV_4, 4, SFX_CAR_HORN_PICKUP, 8670, SFX_CAR_ALARM_1, 8935, 0}, - {SFX_CAR_REV_1, 0, SFX_CAR_HORN_PICKUP, 2000, SFX_CAR_ALARM_1, 17000, 0}, - {SFX_CAR_REV_4, 4, SFX_CAR_HORN_JEEP, 21043, SFX_CAR_ALARM_1, 9935, 0}, - {SFX_CAR_REV_4, 4, SFX_CAR_HORN_JEEP, 21043, SFX_CAR_ALARM_1, 9935, 0}, - {SFX_CAR_REV_5, 5, SFX_CAR_HORN_BMW328, 9003, SFX_CAR_ALARM_1, 9935, 1}, - {SFX_CAR_REV_2, 2, SFX_CAR_HORN_PORSCHE, 12375, SFX_CAR_ALARM_1, 9935, 1}, - {SFX_CAR_REV_5, 5, SFX_CAR_HORN_BUS2, 15554, SFX_CAR_ALARM_1, 9935, 1}, - {SFX_CAR_REV_7, 7, SFX_CAR_HORN_BUS2, 13857, SFX_CAR_ALARM_1, 9935, 0}, - {SFX_CAR_REV_7, 7, SFX_CAR_HORN_PICKUP, 10924, SFX_CAR_ALARM_1, 9935, 0}, - {SFX_CAR_REV_4, 4, SFX_CAR_HORN_JEEP, 21043, SFX_CAR_ALARM_1, 9935, 2}, - {SFX_CAR_REV_1, 0, SFX_CAR_HORN_JEEP, 20143, SFX_CAR_ALARM_1, 9935, 0}, - {SFX_CAR_REV_1, 0, SFX_CAR_HORN_JEEP, 21043, SFX_CAR_ALARM_1, 9935, 0}, - {SFX_CAR_REV_1, 1, SFX_CAR_HORN_JEEP, 21043, SFX_CAR_ALARM_1, 9935, 0}, - {SFX_CAR_REV_1, 1, SFX_CAR_HORN_JEEP, 21043, SFX_CAR_ALARM_1, 9935, 0}, - {SFX_CAR_REV_4, 4, SFX_CAR_HORN_JEEP, 21043, SFX_CAR_ALARM_1, 9000, 0}, - {SFX_CAR_REV_6, 6, SFX_CAR_HORN_TRUCK, 28043, SFX_CAR_ALARM_1, 9935, 2}, - {SFX_CAR_REV_4, 4, SFX_CAR_HORN_BUS, 18286, SFX_CAR_ALARM_1, 9935, 2}, - {SFX_CAR_REV_1, 1, SFX_CAR_HORN_JEEP, 21043, SFX_CAR_ALARM_1, 9935, 0}, - {SFX_CAR_REV_1, 1, SFX_CAR_HORN_56CHEV, 10842, SFX_CAR_ALARM_1, 9935, 0}, - {SFX_CAR_REV_4, 4, SFX_CAR_HORN_BUS2, 18000, SFX_CAR_ALARM_1, 13400, 1}, - {SFX_CAR_REV_1, 1, SFX_CAR_HORN_JEEP, 21043, SFX_CAR_ALARM_1, 9935, 0}, - {SFX_CAR_REV_1, 1, SFX_CAR_HORN_JEEP, 21043, SFX_CAR_ALARM_1, 9935, 0}, - {SFX_CAR_REV_1, 1, SFX_CAR_HORN_JEEP, 21043, SFX_CAR_ALARM_1, 9935, 0}, - {SFX_CAR_REV_1, 1, SFX_CAR_HORN_JEEP, 21043, SFX_CAR_ALARM_1, 9935, 0}, - {SFX_CAR_REV_1, 1, SFX_CAR_HORN_JEEP, 21043, SFX_CAR_ALARM_1, 9935, 0}, - {SFX_CAR_REV_1, 1, SFX_CAR_HORN_JEEP, 21043, SFX_CAR_ALARM_1, 9935, 0}, - {SFX_CAR_REV_1, 1, SFX_CAR_HORN_JEEP, 21043, SFX_CAR_ALARM_1, 9935, 0}, - {SFX_CAR_REV_1, 1, SFX_CAR_HORN_JEEP, 21043, SFX_CAR_ALARM_1, 9935, 0}, - {SFX_CAR_REV_1, 1, SFX_CAR_HORN_JEEP, 21043, SFX_CAR_ALARM_1, 9935, 0}, - {SFX_CAR_REV_1, 1, SFX_CAR_HORN_JEEP, 21043, SFX_CAR_ALARM_1, 9935, 0}, - {SFX_CAR_REV_1, 1, SFX_CAR_HORN_JEEP, 21043, SFX_CAR_ALARM_1, 9935, 0}, - {SFX_CAR_REV_1, 1, SFX_CAR_HORN_JEEP, 21043, SFX_CAR_ALARM_1, 9935, 0}, - {SFX_CAR_REV_1, 1, SFX_CAR_HORN_JEEP, 21043, SFX_CAR_ALARM_1, 9935, 0}, - {SFX_CAR_REV_1, 1, SFX_CAR_HORN_JEEP, 21043, SFX_CAR_ALARM_1, 9935, 0}, - {SFX_CAR_REV_1, 1, SFX_CAR_HORN_JEEP, 21043, SFX_CAR_ALARM_1, 9935, 0}, - {SFX_CAR_REV_1, 1, SFX_CAR_HORN_JEEP, 21043, SFX_CAR_ALARM_1, 9935, 0}, - {SFX_CAR_REV_1, 1, SFX_CAR_HORN_JEEP, 21043, SFX_CAR_ALARM_1, 9935, 0}, - {SFX_CAR_REV_1, 1, SFX_CAR_HORN_JEEP, 21043, SFX_CAR_ALARM_1, 9935, 0}, - {SFX_CAR_REV_1, 1, SFX_CAR_HORN_JEEP, 21043, SFX_CAR_ALARM_1, 9935, 0}, - {SFX_CAR_REV_1, 1, SFX_CAR_HORN_JEEP, 21043, SFX_CAR_ALARM_1, 9935, 0}, - {SFX_CAR_REV_1, 1, SFX_CAR_HORN_JEEP, 21043, SFX_CAR_ALARM_1, 9935, 0}, - {SFX_CAR_REV_1, 1, SFX_CAR_HORN_JEEP, 21043, SFX_CAR_ALARM_1, 9935, 0}, - {SFX_CAR_REV_1, 1, SFX_CAR_HORN_JEEP, 21043, SFX_CAR_ALARM_1, 9935, 0}, - {SFX_CAR_REV_1, 1, SFX_CAR_HORN_JEEP, 21043, SFX_CAR_ALARM_1, 9935, 0}, - {SFX_CAR_REV_1, 1, SFX_CAR_HORN_JEEP, 21043, SFX_CAR_ALARM_1, 9935, 0}, - {SFX_CAR_REV_1, 1, SFX_CAR_HORN_JEEP, 21043, SFX_CAR_ALARM_1, 9935, 0}, - {SFX_CAR_REV_1, 1, SFX_CAR_HORN_JEEP, 21043, SFX_CAR_ALARM_1, 9935, 0}, - {SFX_CAR_REV_1, 1, SFX_CAR_HORN_JEEP, 21043, SFX_CAR_ALARM_1, 9935, 0}, - {SFX_CAR_REV_1, 1, SFX_CAR_HORN_JEEP, 21043, SFX_CAR_ALARM_1, 9935, 0}, - {SFX_CAR_REV_1, 1, SFX_CAR_HORN_JEEP, 21043, SFX_CAR_ALARM_1, 9935, 0}, - {SFX_CAR_REV_1, 1, SFX_CAR_HORN_JEEP, 21043, SFX_CAR_ALARM_1, 9935, 0}, - {SFX_CAR_REV_1, 1, SFX_CAR_HORN_JEEP, 21043, SFX_CAR_ALARM_1, 9935, 0}, - {SFX_CAR_REV_1, 1, SFX_CAR_HORN_JEEP, 21043, SFX_CAR_ALARM_1, 9935, 0}, - {SFX_CAR_REV_1, 1, SFX_CAR_HORN_JEEP, 21043, SFX_CAR_ALARM_1, 9935, 0}, - {SFX_CAR_REV_1, 1, SFX_CAR_HORN_JEEP, 21043, SFX_CAR_ALARM_1, 9935, 0}, - {SFX_CAR_REV_1, 1, SFX_CAR_HORN_JEEP, 21043, SFX_CAR_ALARM_1, 9935, 0}, - {SFX_CAR_REV_1, 1, SFX_CAR_HORN_JEEP, 21043, SFX_CAR_ALARM_1, 9935, 0}, - {SFX_CAR_REV_1, 1, SFX_CAR_HORN_JEEP, 21043, SFX_CAR_ALARM_1, 9935, 0}, - {SFX_CAR_REV_1, 1, SFX_CAR_HORN_JEEP, 21043, SFX_CAR_ALARM_1, 9935, 0}, - {SFX_CAR_REV_1, 1, SFX_CAR_HORN_JEEP, 21043, SFX_CAR_ALARM_1, 9935, 0}, - {SFX_CAR_REV_1, 1, SFX_CAR_HORN_JEEP, 21043, SFX_CAR_ALARM_1, 9935, 0}, - {SFX_CAR_REV_1, 1, SFX_CAR_HORN_JEEP, 21043, SFX_CAR_ALARM_1, 9935, 0}, - {SFX_CAR_REV_1, 1, SFX_CAR_HORN_JEEP, 21043, SFX_CAR_ALARM_1, 9935, 0}, - {SFX_CAR_REV_1, 1, SFX_CAR_HORN_JEEP, 21043, SFX_CAR_ALARM_1, 9935, 0}, - {SFX_CAR_REV_1, 1, SFX_CAR_HORN_JEEP, 21043, SFX_CAR_ALARM_1, 9935, 0}, - {SFX_CAR_REV_1, 1, SFX_CAR_HORN_JEEP, 21043, SFX_CAR_ALARM_1, 9935, 0}, - {SFX_CAR_REV_1, 1, SFX_CAR_HORN_JEEP, 21043, SFX_CAR_ALARM_1, 9935, 0}, - {SFX_CAR_REV_1, 1, SFX_CAR_HORN_JEEP, 21043, SFX_CAR_ALARM_1, 9935, 0}, - {SFX_CAR_REV_1, 1, SFX_CAR_HORN_JEEP, 21043, SFX_CAR_ALARM_1, 9935, 0}, - {SFX_CAR_REV_1, 1, SFX_CAR_HORN_JEEP, 21043, SFX_CAR_ALARM_1, 9935, 0}}; - -void -cAudioManager::ProcessPlayersVehicleEngine(cVehicleParams *params, CAutomobile *automobile) -{ - static int32 GearFreqAdj[] = {6000, 6000, 3400, 1200, 0, -1000}; - - cTransmission *transmission; - float velocityChange; - float relativeVelocityChange; - float accelerationMultipler; - uint8 wheelInUseCounter; - float time; - int baseFreq; - uint8 vol; - int gearNr; - int32 freq; - - int freqModifier; - int soundOffset; - uint8 engineSoundType; - int32 accelerateState; - bool channelUsed; - char lostTraction; - bool processedAccelSampleStopped; - uint8 currentGear; - float gasPedalAudio; - CVector pos; - - static int16 LastAccel = 0; - static int16 LastBrake = 0; - static uint8 CurrentPretendGear = 1; - static bool bLostTractionLastFrame = false; - static bool bHandbrakeOnLastFrame = 0; - static int32 nCruising = 0; - static bool bAccelSampleStopped = true; - - lostTraction = 0; - processedAccelSampleStopped = 0; - if (bPlayerJustEnteredCar) { - bAccelSampleStopped = true; - bPlayerJustEnteredCar = false; - nCruising = 0; - LastAccel = 0; - bLostTractionLastFrame = false; - LastBrake = 0; - bHandbrakeOnLastFrame = 0; - CurrentPretendGear = 1; - } - if (CReplay::IsPlayingBack()) { - accelerateState = 255.f * Max(0.0f, Min(1.0f, automobile->m_fGasPedal)); - } else { - accelerateState = Pads->GetAccelerate(); - } - channelUsed = SampleManager.GetChannelUsedFlag(m_nActiveSamples); - transmission = params->m_pTransmission; - velocityChange = params->m_fVelocityChange; - relativeVelocityChange = 2.0f * velocityChange / transmission->fMaxVelocity; - - accelerationMultipler = Min(Min(1.f, relativeVelocityChange), 0.f); - gasPedalAudio = accelerationMultipler; - currentGear = params->m_pVehicle->m_nCurrentGear; - - if (transmission->nDriveType == '4') { - wheelInUseCounter = 0; - for (uint8 i = 0; i < ARRAY_SIZE(automobile->m_aWheelState); i++) { - if (automobile->m_aWheelState[i]) - ++wheelInUseCounter; - } - if (wheelInUseCounter > 2) - lostTraction = 1; - } else if (transmission->nDriveType == 'F') { - if ((automobile->m_aWheelState[0] || automobile->m_aWheelState[2]) && (automobile->m_aWheelState[1] || automobile->m_aWheelState[3])) { - lostTraction = 1; - } - } else if (transmission->nDriveType == 'R' && (automobile->m_aWheelState[1] || automobile->m_aWheelState[3])) { - lostTraction = 1; - } - if (0.0f != velocityChange) { - time = params->m_pVehicle->m_vecMoveSpeed.z / velocityChange; - if (time <= 0.0f) { - freqModifier = Max(-0.2f, time) * -15000.f; - } else { - freqModifier = -(Min(0.2f, time) * 15000.f); - } - if (params->m_fVelocityChange < -0.001f) - freqModifier = -freqModifier; - } else { - freqModifier = 0; - } - engineSoundType = aVehicleSettings[params->m_nIndex].m_bEngineSoundType; - soundOffset = 3 * (engineSoundType - 1); - if (accelerateState <= 0) { - if (params->m_fVelocityChange < -0.001f) { - if (channelUsed) { - SampleManager.StopChannel(m_nActiveSamples); - bAccelSampleStopped = true; - } - if (!automobile->m_nWheelsOnGround || automobile->bIsHandbrakeOn || lostTraction) { - gasPedalAudio = automobile->m_fGasPedalAudio; - } else { - gasPedalAudio = Min(1.0f, params->m_fVelocityChange / params->m_pTransmission->fMaxReverseVelocity); - } - gasPedalAudio = Max(0.0f, gasPedalAudio); - automobile->m_fGasPedalAudio = gasPedalAudio; - } else if (LastAccel > 0) { - if (channelUsed) { - SampleManager.StopChannel(m_nActiveSamples); - bAccelSampleStopped = true; - } - nCruising = 0; - if (!automobile->m_nWheelsOnGround || automobile->bIsHandbrakeOn || lostTraction || - params->m_fVelocityChange >= 0.01f && automobile->m_fGasPedalAudio > 0.2f) { - automobile->m_fGasPedalAudio = automobile->m_fGasPedalAudio * 0.6f; - gasPedalAudio = automobile->m_fGasPedalAudio; - } - if (gasPedalAudio > 0.05f) { - freq = (5000.f * (gasPedalAudio - 0.05f) * 20.f / 19) + 19000; - if (engineSoundType == 6) - freq /= 2; - AddPlayerCarSample((25.f * (gasPedalAudio - 0.05f) * 20.f / 19) + 40, freq, (soundOffset + SFX_CAR_FINGER_OFF_ACCEL_1), engineSoundType, 63, 0); - } - } - freq = (10000.f * gasPedalAudio) + 22050; - if (engineSoundType == 6) - freq /= 2; - AddPlayerCarSample(110 - (40.f * gasPedalAudio), freq, (engineSoundType + SFX_CAR_REV_10), 0, 52, 1); - - CurrentPretendGear = Max(1, currentGear); - LastAccel = accelerateState; - - bHandbrakeOnLastFrame = automobile->bIsHandbrakeOn; - bLostTractionLastFrame = lostTraction; - return; - } - if (!nCruising) { - if (accelerateState < 150 || !automobile->m_nWheelsOnGround || automobile->bIsHandbrakeOn || lostTraction || - currentGear < 2 && velocityChange - automobile->m_fVelocityChangeForAudio < 0.01f) { // here could be used abs - if (!automobile->m_nWheelsOnGround || automobile->bIsHandbrakeOn || lostTraction) { - if (!automobile->m_nWheelsOnGround && automobile->m_nDriveWheelsOnGround || - (automobile->bIsHandbrakeOn && !bHandbrakeOnLastFrame || lostTraction && !bLostTractionLastFrame) && automobile->m_nWheelsOnGround) { - automobile->m_fGasPedalAudio = automobile->m_fGasPedalAudio * 0.6f; - } - freqModifier = 0; - baseFreq = (15000.f * automobile->m_fGasPedalAudio) + 14000; - vol = (25.0f * automobile->m_fGasPedalAudio) + 60; - } else { - baseFreq = (8000.f * accelerationMultipler) + 16000; - vol = (25.0f * accelerationMultipler) + 60; - automobile->m_fGasPedalAudio = accelerationMultipler; - } - freq = freqModifier + baseFreq; - if (engineSoundType == 6) - freq /= 2; - if (channelUsed) { - SampleManager.StopChannel(m_nActiveSamples); - bAccelSampleStopped = true; - } - AddPlayerCarSample(vol, freq, (engineSoundType + SFX_PHONE_RING), 0, 2, 1); - LastAccel = accelerateState; - - bHandbrakeOnLastFrame = automobile->bIsHandbrakeOn; - bLostTractionLastFrame = lostTraction; - return; - } - TranslateEntity(&m_sQueueSample.m_vecPos, &pos); - if (bAccelSampleStopped) { - if (CurrentPretendGear != 1 || currentGear != 2) { - gearNr = currentGear - 1; - if (gearNr < 1) - gearNr = 1; - CurrentPretendGear = gearNr; - } - processedAccelSampleStopped = 1; - bAccelSampleStopped = false; - } - if (channelUsed) { - SampleManager.SetChannelEmittingVolume(m_nActiveSamples, 85); - SampleManager.SetChannel3DPosition(m_nActiveSamples, pos.x, pos.y, pos.z); - SampleManager.SetChannel3DDistances(m_nActiveSamples, 50.f, 12.5f); - if (engineSoundType == 6) - freq = (GearFreqAdj[CurrentPretendGear] + freqModifier + 22050) / 2; - else - freq = GearFreqAdj[CurrentPretendGear] + freqModifier + 22050; - SampleManager.SetChannelFrequency(m_nActiveSamples, freq); - if (!channelUsed) { - SampleManager.SetChannelReverbFlag(m_nActiveSamples, m_bDynamicAcousticModelingStatus != 0); - SampleManager.StartChannel(m_nActiveSamples); - } - LastAccel = accelerateState; - - bHandbrakeOnLastFrame = automobile->bIsHandbrakeOn; - bLostTractionLastFrame = lostTraction; - return; - } - if (processedAccelSampleStopped) { - if (!SampleManager.InitialiseChannel(m_nActiveSamples, soundOffset + 345, 0)) - return; - SampleManager.SetChannelLoopCount(m_nActiveSamples, 1); - SampleManager.SetChannelLoopPoints(m_nActiveSamples, 0, -1); - SampleManager.SetChannelEmittingVolume(m_nActiveSamples, 85); - SampleManager.SetChannel3DPosition(m_nActiveSamples, pos.x, pos.y, pos.z); - SampleManager.SetChannel3DDistances(m_nActiveSamples, 50.f, 12.5f); - freq = GearFreqAdj[CurrentPretendGear] + freqModifier + 22050; - if (engineSoundType == 6) - freq /= 2; - SampleManager.SetChannelFrequency(m_nActiveSamples, freq); - if (!channelUsed) { - SampleManager.SetChannelReverbFlag(m_nActiveSamples, m_bDynamicAcousticModelingStatus != 0); - SampleManager.StartChannel(m_nActiveSamples); - } - LastAccel = accelerateState; - - bHandbrakeOnLastFrame = automobile->bIsHandbrakeOn; - bLostTractionLastFrame = lostTraction; - return; - } - if (CurrentPretendGear < params->m_pTransmission->nNumberOfGears - 1) { - ++CurrentPretendGear; - if (!SampleManager.InitialiseChannel(m_nActiveSamples, soundOffset + 345, 0)) - return; - SampleManager.SetChannelLoopCount(m_nActiveSamples, 1); - SampleManager.SetChannelLoopPoints(m_nActiveSamples, 0, -1); - SampleManager.SetChannelEmittingVolume(m_nActiveSamples, 85); - SampleManager.SetChannel3DPosition(m_nActiveSamples, pos.x, pos.y, pos.z); - SampleManager.SetChannel3DDistances(m_nActiveSamples, 50.f, 12.5f); - freq = GearFreqAdj[CurrentPretendGear] + freqModifier + 22050; - if (engineSoundType == 6) - freq /= 2; - SampleManager.SetChannelFrequency(m_nActiveSamples, freq); - if (!channelUsed) { - SampleManager.SetChannelReverbFlag(m_nActiveSamples, m_bDynamicAcousticModelingStatus != 0); - SampleManager.StartChannel(m_nActiveSamples); - } - LastAccel = accelerateState; - - bHandbrakeOnLastFrame = automobile->bIsHandbrakeOn; - bLostTractionLastFrame = lostTraction; - return; - } - nCruising = 1; - } - bAccelSampleStopped = true; - if (accelerateState < 150 || !automobile->m_nWheelsOnGround || automobile->bIsHandbrakeOn || lostTraction || - currentGear < params->m_pTransmission->nNumberOfGears - 1) { - nCruising = 0; - } else { - if (accelerateState >= 220 && 0.001f + params->m_fVelocityChange < automobile->m_fVelocityChangeForAudio) { - if (nCruising < 800) - ++nCruising; - } else if (nCruising > 3) { - --nCruising; - } - freq = 27 * nCruising + freqModifier + 22050; - if (engineSoundType == 6) - freq /= 2; - AddPlayerCarSample(85, freq, (soundOffset + SFX_CAR_AFTER_ACCEL_1), engineSoundType, 64, 1); - } - LastAccel = accelerateState; - - bHandbrakeOnLastFrame = automobile->bIsHandbrakeOn; - bLostTractionLastFrame = lostTraction; -} - -void -cAudioManager::ProcessPoliceCellBeatingScriptObject(uint8 sound) -{ - uint32 time = CTimer::GetTimeInMilliseconds(); - int32 sampleIndex; - uint8 emittingVol; - float distSquared; - cPedParams params; - - static uint8 counter = 0; - - if (time > gCellNextTime) { - switch (sound) { - case SCRIPT_SOUND_POLICE_CELL_BEATING_LOOP_S: - m_sQueueSample.m_fSoundIntensity = scriptObjectIntensityS; - break; - case SCRIPT_SOUND_POLICE_CELL_BEATING_LOOP_L: - m_sQueueSample.m_fSoundIntensity = scriptObjectIntensityL; - break; - default: - return; - } - distSquared = GetDistanceSquared(m_sQueueSample.m_vecPos); - if (distSquared < SQR(m_sQueueSample.m_fSoundIntensity)) { - m_sQueueSample.m_fDistance = Sqrt(distSquared); - if (m_FrameCounter & 1) - sampleIndex = (m_anRandomTable[1] & 3) + SFX_FIGHT_1; - else - sampleIndex = (m_anRandomTable[3] & 1) + SFX_BAT_HIT_LEFT; - m_sQueueSample.m_nSampleIndex = sampleIndex; - emittingVol = m_anRandomTable[0] % 50 + 55; - m_sQueueSample.m_nVolume = ComputeVolume(emittingVol, m_sQueueSample.m_fSoundIntensity, m_sQueueSample.m_fDistance); - if (m_sQueueSample.m_nVolume) { - m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; - m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(m_sQueueSample.m_nSampleIndex); - m_sQueueSample.m_nFrequency += RandomDisplacement(m_sQueueSample.m_nFrequency / 16); - m_sQueueSample.m_nCounter = counter++; - m_sQueueSample.m_bIs2D = false; - m_sQueueSample.m_nLoopCount = 1; - m_sQueueSample.m_bReleasingSoundFlag = true; - m_sQueueSample.m_nReleasingVolumeModificator = 3; - m_sQueueSample.m_fSpeedMultiplier = 0.0f; - m_sQueueSample.m_nEmittingVolume = emittingVol; - m_sQueueSample.m_nLoopStart = 0; - m_sQueueSample.m_nLoopEnd = -1; - m_sQueueSample.m_bReverbFlag = true; - m_sQueueSample.m_bRequireReflection = false; - AddSampleToRequestedQueue(); - params.m_bDistanceCalculated = true; - params.m_fDistance = distSquared; - params.m_pPed = nil; - SetupPedComments(¶ms, SOUND_INJURED_PED_MALE_PRISON); - } - gCellNextTime = time + 500 + m_anRandomTable[3] % 1500; - } - } -} - -void -cAudioManager::ProcessPornCinema(uint8 sound) -{ - - eSfxSample sample; - uint32 time; - int32 rand; - float distSquared; - - switch (sound) { - case SCRIPT_SOUND_PORN_CINEMA_1_S: - case SCRIPT_SOUND_MISTY_SEX_S: - m_sQueueSample.m_nSampleIndex = SFX_PORN_1_LOOP; - m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; - sample = SFX_PORN_1_GROAN_1; - m_sQueueSample.m_fSoundIntensity = 20.0f; - break; - case SCRIPT_SOUND_PORN_CINEMA_1_L: - case SCRIPT_SOUND_MISTY_SEX_L: - m_sQueueSample.m_nSampleIndex = SFX_PORN_1_LOOP; - m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; - sample = SFX_PORN_1_GROAN_1; - m_sQueueSample.m_fSoundIntensity = 80.0f; - break; - case SCRIPT_SOUND_PORN_CINEMA_2_S: - m_sQueueSample.m_nSampleIndex = SFX_PORN_2_LOOP; - m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; - sample = SFX_PORN_2_GROAN_1; - m_sQueueSample.m_fSoundIntensity = 20.0f; - break; - case SCRIPT_SOUND_PORN_CINEMA_2_L: - m_sQueueSample.m_nSampleIndex = SFX_PORN_2_LOOP; - m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; - sample = SFX_PORN_2_GROAN_1; - m_sQueueSample.m_fSoundIntensity = 80.0f; - break; - case SCRIPT_SOUND_PORN_CINEMA_3_S: - m_sQueueSample.m_nSampleIndex = SFX_PORN_3_LOOP; - m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; - m_sQueueSample.m_fSoundIntensity = 20.0f; - sample = SFX_PORN_3_GROAN_1; - break; - case SCRIPT_SOUND_PORN_CINEMA_3_L: - m_sQueueSample.m_nSampleIndex = SFX_PORN_3_LOOP; - m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; - m_sQueueSample.m_fSoundIntensity = 80.0f; - sample = SFX_PORN_3_GROAN_1; - break; - default: - return; - } - distSquared = GetDistanceSquared(m_sQueueSample.m_vecPos); - if (distSquared < SQR(m_sQueueSample.m_fSoundIntensity)) { - m_sQueueSample.m_fDistance = Sqrt(distSquared); - if (sound != SCRIPT_SOUND_MISTY_SEX_S && sound != SCRIPT_SOUND_MISTY_SEX_L) { - m_sQueueSample.m_nVolume = ComputeVolume(maxVolume, m_sQueueSample.m_fSoundIntensity, m_sQueueSample.m_fDistance); - if (m_sQueueSample.m_nVolume) { - m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(m_sQueueSample.m_nSampleIndex); - m_sQueueSample.m_nCounter = 0; - m_sQueueSample.m_bIs2D = false; - m_sQueueSample.m_nLoopCount = 0; - m_sQueueSample.m_bReleasingSoundFlag = false; - m_sQueueSample.m_nReleasingVolumeModificator = 3; - m_sQueueSample.m_fSpeedMultiplier = 2.0f; - m_sQueueSample.m_nEmittingVolume = maxVolume; - m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex); - m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex); - m_sQueueSample.m_bReverbFlag = true; - m_sQueueSample.m_bRequireReflection = false; - AddSampleToRequestedQueue(); - } - } - - time = CTimer::GetTimeInMilliseconds(); - if (time > gPornNextTime) { - m_sQueueSample.m_nVolume = ComputeVolume(90, m_sQueueSample.m_fSoundIntensity, m_sQueueSample.m_fDistance); - if (m_sQueueSample.m_nVolume) { - rand = m_anRandomTable[1] & 1; - m_sQueueSample.m_nSampleIndex = rand + sample; - m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(m_sQueueSample.m_nSampleIndex); - m_sQueueSample.m_nFrequency += RandomDisplacement(m_sQueueSample.m_nFrequency / 16); - m_sQueueSample.m_nCounter = rand + 1; - m_sQueueSample.m_bIs2D = false; - m_sQueueSample.m_nLoopCount = 1; - m_sQueueSample.m_bReleasingSoundFlag = true; - m_sQueueSample.m_nReleasingVolumeModificator = 6; - m_sQueueSample.m_fSpeedMultiplier = 0.0f; - m_sQueueSample.m_nLoopStart = 0; - m_sQueueSample.m_nLoopEnd = -1; - m_sQueueSample.m_bReverbFlag = true; - m_sQueueSample.m_bRequireReflection = false; - AddSampleToRequestedQueue(); - gPornNextTime = time + 2000 + m_anRandomTable[3] % 6000; - } - } - } -} - -void -cAudioManager::ProcessProjectiles() -{ - uint8 emittingVol; - - for (int32 i = 0; i < NUM_PROJECTILES; i++) { - if (CProjectileInfo::GetProjectileInfo(i)->m_bInUse) { - switch (CProjectileInfo::GetProjectileInfo(i)->m_eWeaponType) { - case WEAPONTYPE_ROCKETLAUNCHER: - emittingVol = maxVolume; - m_sQueueSample.m_fSoundIntensity = rocketLauncherIntensity; - m_sQueueSample.m_nSampleIndex = SFX_ROCKET_FLY; - m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; - m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_ROCKET_FLY); - m_sQueueSample.m_nReleasingVolumeModificator = 3; - break; - case WEAPONTYPE_MOLOTOV: - emittingVol = molotovVolume; - m_sQueueSample.m_fSoundIntensity = molotovIntensity; - m_sQueueSample.m_nSampleIndex = SFX_PED_ON_FIRE; - m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; - m_sQueueSample.m_nFrequency = 32 * SampleManager.GetSampleBaseFrequency(SFX_PED_ON_FIRE) / 25; - m_sQueueSample.m_nReleasingVolumeModificator = 7; - break; - default: - return; - } - m_sQueueSample.m_fSpeedMultiplier = 4.0f; - m_sQueueSample.m_nReleasingVolumeDivider = 3; - m_sQueueSample.m_vecPos = CProjectileInfo::ms_apProjectile[i]->GetPosition(); - float distSquared = GetDistanceSquared(m_sQueueSample.m_vecPos); - if (distSquared < SQR(m_sQueueSample.m_fSoundIntensity)) { - m_sQueueSample.m_fDistance = Sqrt(distSquared); - m_sQueueSample.m_nVolume = ComputeVolume(emittingVol, m_sQueueSample.m_fSoundIntensity, m_sQueueSample.m_fDistance); - if (m_sQueueSample.m_nVolume) { - m_sQueueSample.m_nCounter = i; - m_sQueueSample.m_bIs2D = false; - m_sQueueSample.m_nLoopCount = 0; - m_sQueueSample.m_nEmittingVolume = emittingVol; - m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex); - m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex); - m_sQueueSample.m_bReleasingSoundFlag = false; - m_sQueueSample.m_bReverbFlag = true; - m_sQueueSample.m_bRequireReflection = false; - AddSampleToRequestedQueue(); - } - } - } - } -} - -void -cAudioManager::ProcessRainOnVehicle(cVehicleParams *params) -{ - if (params->m_fDistance < SQR(rainOnVehicleIntensity) && CWeather::Rain > 0.01f && (!CCullZones::CamNoRain() || !CCullZones::PlayerNoRain())) { - CVehicle *veh = params->m_pVehicle; - ++veh->m_bRainAudioCounter; - if (veh->m_bRainAudioCounter >= 2) { - veh->m_bRainAudioCounter = 0; - CalculateDistance(params->m_bDistanceCalculated, params->m_fDistance); - float emittingVol = 30.f * CWeather::Rain; - m_sQueueSample.m_nVolume = ComputeVolume(emittingVol, rainOnVehicleIntensity, m_sQueueSample.m_fDistance); - if (m_sQueueSample.m_nVolume) { - m_sQueueSample.m_nCounter = veh->m_bRainSamplesCounter++; - if (veh->m_bRainSamplesCounter > 4) - veh->m_bRainSamplesCounter = 68; - m_sQueueSample.m_nSampleIndex = (m_anRandomTable[1] & 3) + SFX_CAR_RAIN_1; - m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; - m_sQueueSample.m_bIs2D = false; - m_sQueueSample.m_nReleasingVolumeModificator = 9; - m_sQueueSample.m_nFrequency = m_anRandomTable[1] % 4000 + 28000; - m_sQueueSample.m_nLoopCount = 1; - m_sQueueSample.m_nEmittingVolume = (uint8)emittingVol; - m_sQueueSample.m_nLoopStart = 0; - m_sQueueSample.m_nLoopEnd = -1; - m_sQueueSample.m_fSpeedMultiplier = 0.0f; - m_sQueueSample.m_fSoundIntensity = rainOnVehicleIntensity; - m_sQueueSample.m_bReleasingSoundFlag = true; - m_sQueueSample.m_bReverbFlag = false; - m_sQueueSample.m_bRequireReflection = false; - AddSampleToRequestedQueue(); - } - } - } -} - -void -cAudioManager::ProcessReverb() const -{ - if (SampleManager.UpdateReverb() && m_bDynamicAcousticModelingStatus) { - for (uint32 i = 0; i < -#ifdef FIX_BUGS - channels -#else - 28 -#endif - ; - i++) { - if (m_asActiveSamples[i].m_bReverbFlag) - SampleManager.SetChannelReverbFlag(i, 1); - } - } -} - -bool -cAudioManager::ProcessReverseGear(cVehicleParams *params) -{ - CVehicle *veh; - CAutomobile *automobile; - int32 emittingVol; - float modificator; - - if (params->m_fDistance >= SQR(reverseGearIntensity)) - return false; - veh = params->m_pVehicle; - if (veh->bEngineOn && (veh->m_fGasPedal < 0.0f || !veh->m_nCurrentGear)) { - CalculateDistance(params->m_bDistanceCalculated, params->m_fDistance); - automobile = (CAutomobile *)params->m_pVehicle; - if (automobile->m_nWheelsOnGround) { - modificator = params->m_fVelocityChange / params->m_pTransmission->fMaxReverseVelocity; - } else { - if (automobile->m_nDriveWheelsOnGround) - automobile->m_fGasPedalAudio = automobile->m_fGasPedalAudio * 0.4f; - modificator = automobile->m_fGasPedalAudio; - } - modificator = Abs(modificator); - emittingVol = (24.f * modificator); - m_sQueueSample.m_nVolume = ComputeVolume(emittingVol, reverseGearIntensity, m_sQueueSample.m_fDistance); - if (m_sQueueSample.m_nVolume) { - if (params->m_pVehicle->m_fGasPedal >= 0.0f) { - m_sQueueSample.m_nCounter = 62; - m_sQueueSample.m_nSampleIndex = SFX_REVERSE_GEAR_2; - } else { - m_sQueueSample.m_nCounter = 61; - m_sQueueSample.m_nSampleIndex = SFX_REVERSE_GEAR; - } - m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; - m_sQueueSample.m_bIs2D = false; - m_sQueueSample.m_nReleasingVolumeModificator = 3; - m_sQueueSample.m_nFrequency = (6000.f * modificator) + 7000; - m_sQueueSample.m_nLoopCount = 0; - m_sQueueSample.m_nEmittingVolume = emittingVol; - m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex); - m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex); - m_sQueueSample.m_fSpeedMultiplier = 3.0f; - m_sQueueSample.m_fSoundIntensity = reverseGearIntensity; - m_sQueueSample.m_bReleasingSoundFlag = false; - m_sQueueSample.m_nReleasingVolumeDivider = 5; - m_sQueueSample.m_bReverbFlag = true; - m_sQueueSample.m_bRequireReflection = false; - AddSampleToRequestedQueue(); - } - } - return true; -} - -void -cAudioManager::ProcessSawMillScriptObject(uint8 sound) -{ - uint32 time; - float distSquared; - - switch (sound) { - case SCRIPT_SOUND_SAWMILL_LOOP_S: - case SCRIPT_SOUND_SAWMILL_LOOP_L: - m_sQueueSample.m_fSoundIntensity = scriptObjectIntensityS; - break; - default: - return; - } - distSquared = GetDistanceSquared(m_sQueueSample.m_vecPos); - if (distSquared < SQR(m_sQueueSample.m_fSoundIntensity)) { - m_sQueueSample.m_fDistance = Sqrt(distSquared); - m_sQueueSample.m_nVolume = ComputeVolume(30, m_sQueueSample.m_fSoundIntensity, m_sQueueSample.m_fDistance); - if (m_sQueueSample.m_nVolume) { - m_sQueueSample.m_nSampleIndex = SFX_SAWMILL_LOOP; - m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; - m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_SAWMILL_LOOP); - m_sQueueSample.m_nCounter = 0; - m_sQueueSample.m_bIs2D = false; - m_sQueueSample.m_nLoopCount = 0; - m_sQueueSample.m_bReleasingSoundFlag = false; - m_sQueueSample.m_nReleasingVolumeModificator = 5; - m_sQueueSample.m_fSpeedMultiplier = 2.0f; - m_sQueueSample.m_nEmittingVolume = 30; - m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex); - m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex); - m_sQueueSample.m_bReverbFlag = true; - m_sQueueSample.m_bRequireReflection = false; - AddSampleToRequestedQueue(); - } - time = CTimer::GetTimeInMilliseconds(); - if (time > gSawMillNextTime) { - m_sQueueSample.m_nVolume = ComputeVolume(70, m_sQueueSample.m_fSoundIntensity, m_sQueueSample.m_fDistance); - if (m_sQueueSample.m_nVolume) { - m_sQueueSample.m_nSampleIndex = SFX_SAWMILL_CUT_WOOD; - m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; - m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(m_sQueueSample.m_nSampleIndex); - m_sQueueSample.m_nCounter = 1; - m_sQueueSample.m_bIs2D = false; - m_sQueueSample.m_nLoopCount = 1; - m_sQueueSample.m_bReleasingSoundFlag = true; - m_sQueueSample.m_nReleasingVolumeModificator = 3; - m_sQueueSample.m_fSpeedMultiplier = 2.0f; - m_sQueueSample.m_nLoopStart = 0; - m_sQueueSample.m_nLoopEnd = -1; - m_sQueueSample.m_bReverbFlag = true; - m_sQueueSample.m_bRequireReflection = false; - AddSampleToRequestedQueue(); - gSawMillNextTime = time + 2000 + m_anRandomTable[3] % 4000; - } - } - } -} - -void -cAudioManager::ProcessScriptObject(int32 id) -{ - cAudioScriptObject *entity = (cAudioScriptObject *)m_asAudioEntities[id].m_pEntity; - if (entity) { - m_sQueueSample.m_vecPos = entity->Posn; - if (m_asAudioEntities[id].m_AudioEvents == 1) - ProcessOneShotScriptObject(m_asAudioEntities[id].m_awAudioEvent[0]); - else - ProcessLoopingScriptObject(entity->AudioId); - } -} - -void -cAudioManager::ProcessShopScriptObject(uint8 sound) -{ - uint32 time; - int32 rand; - float distSquared; - - switch (sound) { - case SCRIPT_SOUND_SHOP_LOOP_S: - case SCRIPT_SOUND_SHOP_LOOP_L: - m_sQueueSample.m_fSoundIntensity = 30.0f; - break; - default: - return; - } - distSquared = GetDistanceSquared(m_sQueueSample.m_vecPos); - if (distSquared < SQR(m_sQueueSample.m_fSoundIntensity)) { - m_sQueueSample.m_fDistance = Sqrt(distSquared); - m_sQueueSample.m_nVolume = ComputeVolume(30, m_sQueueSample.m_fSoundIntensity, m_sQueueSample.m_fDistance); - if (m_sQueueSample.m_nVolume) { - m_sQueueSample.m_nSampleIndex = SFX_SHOP_LOOP; - m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; - m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_SHOP_LOOP); - m_sQueueSample.m_nCounter = 0; - m_sQueueSample.m_bIs2D = false; - m_sQueueSample.m_nLoopCount = 0; - m_sQueueSample.m_bReleasingSoundFlag = false; - m_sQueueSample.m_nReleasingVolumeModificator = 5; - m_sQueueSample.m_fSpeedMultiplier = 2.0f; - m_sQueueSample.m_nEmittingVolume = 30; - m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex); - m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex); - m_sQueueSample.m_bReverbFlag = true; - m_sQueueSample.m_bRequireReflection = false; - AddSampleToRequestedQueue(); - } - time = CTimer::GetTimeInMilliseconds(); - if (time > gShopNextTime) { - m_sQueueSample.m_nVolume = ComputeVolume(70, m_sQueueSample.m_fSoundIntensity, m_sQueueSample.m_fDistance); - if (m_sQueueSample.m_nVolume) { - rand = m_anRandomTable[1] & 1; - m_sQueueSample.m_nSampleIndex = rand + SFX_SHOP_TILL_1; - m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; - m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(m_sQueueSample.m_nSampleIndex); - m_sQueueSample.m_nCounter = rand + 1; - m_sQueueSample.m_bIs2D = false; - m_sQueueSample.m_nLoopCount = 1; - m_sQueueSample.m_bReleasingSoundFlag = true; - m_sQueueSample.m_nReleasingVolumeModificator = 3; - m_sQueueSample.m_fSpeedMultiplier = 2.0f; - m_sQueueSample.m_nEmittingVolume = 70; - m_sQueueSample.m_nLoopStart = 0; - m_sQueueSample.m_nLoopEnd = -1; - m_sQueueSample.m_bReverbFlag = true; - m_sQueueSample.m_bRequireReflection = false; - AddSampleToRequestedQueue(); - gShopNextTime = time + 3000 + m_anRandomTable[3] % 7000; - } - } - } -} - -void -cAudioManager::ProcessSpecial() -{ - if (m_nUserPause) { - if (!m_nPreviousUserPause) { - MusicManager.ChangeMusicMode(MUSICMODE_FRONTEND); - SampleManager.SetEffectsFadeVolume(maxVolume); - SampleManager.SetMusicFadeVolume(maxVolume); - } - } else { - if (m_nPreviousUserPause) { - MusicManager.StopFrontEndTrack(); - MusicManager.ChangeMusicMode(MUSICMODE_GAME); - } - CPlayerPed *playerPed = FindPlayerPed(); - if (playerPed) { - const PedState &state = playerPed->m_nPedState; - if (state != PED_ENTER_CAR && state != PED_STEAL_CAR && !playerPed->bInVehicle) - SampleManager.StopChannel(m_nActiveSamples); - } - } -} - -bool -cAudioManager::ProcessTrainNoise(cVehicleParams *params) -{ - const float SOUND_INTENSITY = 300.0f; - - CTrain *train; - uint8 emittingVol; - float speedMultipler; - - if (params->m_fDistance >= SQR(SOUND_INTENSITY)) - return false; - - if (params->m_fVelocityChange > 0.0f) { - CalculateDistance(params->m_bDistanceCalculated, params->m_fDistance); - train = (CTrain *)params->m_pVehicle; - speedMultipler = Min(1.0f, train->m_fSpeed * 250.f / 51.f); - emittingVol = (75.f * speedMultipler); - if (train->m_fWagonPosition == 0.0f) { - m_sQueueSample.m_nVolume = ComputeVolume(emittingVol, SOUND_INTENSITY, m_sQueueSample.m_fDistance); - if (m_sQueueSample.m_nVolume != 0) { - m_sQueueSample.m_nCounter = 32; - m_sQueueSample.m_nSampleIndex = SFX_TRAIN_FAR; - m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; - m_sQueueSample.m_bIs2D = false; - m_sQueueSample.m_nReleasingVolumeModificator = 2; - m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_TRAIN_FAR); - m_sQueueSample.m_nLoopCount = 0; - m_sQueueSample.m_nEmittingVolume = emittingVol; - m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex); - m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex); - m_sQueueSample.m_fSpeedMultiplier = 3.0f; - m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY; - m_sQueueSample.m_bReleasingSoundFlag = false; - m_sQueueSample.m_nReleasingVolumeDivider = 3; - m_sQueueSample.m_bReverbFlag = true; - m_sQueueSample.m_bRequireReflection = false; - AddSampleToRequestedQueue(); - } - } - const float SOUND_INTENSITY = 70.0f; - if (params->m_fDistance < SQR(SOUND_INTENSITY)) { - m_sQueueSample.m_nVolume = ComputeVolume(emittingVol, SOUND_INTENSITY, m_sQueueSample.m_fDistance); - if (m_sQueueSample.m_nVolume != 0) { - m_sQueueSample.m_nCounter = 33; - m_sQueueSample.m_nSampleIndex = SFX_TRAIN_NEAR; - m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; - m_sQueueSample.m_bIs2D = false; - m_sQueueSample.m_nReleasingVolumeModificator = 5; - m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_TRAIN_NEAR) + 100 * m_sQueueSample.m_nEntityIndex % 987; - m_sQueueSample.m_nLoopCount = 0; - m_sQueueSample.m_nEmittingVolume = emittingVol; - m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex); - m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex); - m_sQueueSample.m_fSpeedMultiplier = 6.0f; - m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY; - m_sQueueSample.m_bReleasingSoundFlag = false; - m_sQueueSample.m_nReleasingVolumeDivider = 3; - m_sQueueSample.m_bReverbFlag = true; - m_sQueueSample.m_bRequireReflection = false; - AddSampleToRequestedQueue(); - } - } - } - return true; -} - -void -cAudioManager::ProcessVehicle(CVehicle *veh) -{ - tHandlingData *handling = veh->pHandling; - float velChange; - cVehicleParams params; - m_sQueueSample.m_vecPos = veh->GetPosition(); - - params.m_bDistanceCalculated = false; - params.m_fDistance = GetDistanceSquared(m_sQueueSample.m_vecPos); - params.m_pVehicle = veh; - params.m_pTransmission = nil; - params.m_nIndex = 0; - params.m_fVelocityChange = 0.0f; - - if (handling) - params.m_pTransmission = &handling->Transmission; - - params.m_nIndex = veh->GetModelIndex() - MI_FIRST_VEHICLE; - if (params.m_pVehicle->GetStatus() == STATUS_SIMPLE) - velChange = params.m_pVehicle->AutoPilot.m_fMaxTrafficSpeed * 0.02f; - else - velChange = DotProduct(params.m_pVehicle->m_vecMoveSpeed, params.m_pVehicle->GetForward()); - params.m_fVelocityChange = velChange; - switch (params.m_pVehicle->m_vehType) { - case VEHICLE_TYPE_CAR: - UpdateGasPedalAudio((CAutomobile *)veh); - if (params.m_nIndex == RCBANDIT) { - ProcessModelCarEngine(¶ms); - ProcessVehicleOneShots(¶ms); - ((CAutomobile *)veh)->m_fVelocityChangeForAudio = params.m_fVelocityChange; - ProcessRainOnVehicle(¶ms); - break; - } - if (params.m_nIndex == DODO) { - if (!ProcessVehicleRoadNoise(¶ms)) { - ProcessVehicleOneShots(¶ms); - ((CAutomobile *)veh)->m_fVelocityChangeForAudio = params.m_fVelocityChange; - ProcessRainOnVehicle(¶ms); - break; - } - if (CWeather::WetRoads > 0.f) - ProcessWetRoadNoise(¶ms); - ProcessVehicleSkidding(¶ms); - } else { - if (!ProcessVehicleRoadNoise(¶ms)) { - ProcessVehicleOneShots(¶ms); - ((CAutomobile *)veh)->m_fVelocityChangeForAudio = params.m_fVelocityChange; - ProcessRainOnVehicle(¶ms); - break; - } - ProcessReverseGear(¶ms); - if (CWeather::WetRoads > 0.f) - ProcessWetRoadNoise(¶ms); - ProcessVehicleSkidding(¶ms); - ProcessVehicleHorn(¶ms); - ProcessVehicleSirenOrAlarm(¶ms); - if (UsesReverseWarning(params.m_nIndex)) - ProcessVehicleReverseWarning(¶ms); - if (HasAirBrakes(params.m_nIndex)) - ProcessAirBrakes(¶ms); - } - ProcessCarBombTick(¶ms); - ProcessVehicleEngine(¶ms); - ProcessEngineDamage(¶ms); - ProcessVehicleDoors(¶ms); - ProcessVehicleOneShots(¶ms); - ((CAutomobile *)veh)->m_fVelocityChangeForAudio = params.m_fVelocityChange; - ProcessRainOnVehicle(¶ms); - break; - case VEHICLE_TYPE_BOAT: - ProcessBoatEngine(¶ms); - ProcessBoatMovingOverWater(¶ms); - ProcessVehicleOneShots(¶ms); - ProcessRainOnVehicle(¶ms); - break; - case VEHICLE_TYPE_TRAIN: - ProcessTrainNoise(¶ms); - ProcessVehicleOneShots(¶ms); - ProcessRainOnVehicle(¶ms); - break; - case VEHICLE_TYPE_HELI: - ProcessHelicopter(¶ms); - ProcessVehicleOneShots(¶ms); - ProcessRainOnVehicle(¶ms); - break; - case VEHICLE_TYPE_PLANE: - ProcessPlane(¶ms); - ProcessVehicleOneShots(¶ms); - ProcessRainOnVehicle(¶ms); - break; - default: - ProcessRainOnVehicle(¶ms); - break; - } -} - -bool -cAudioManager::ProcessVehicleDoors(cVehicleParams *params) -{ - const float SOUND_INTENSITY = 40.0f; - - CAutomobile *automobile; - int8 doorState; - int32 emittingVol; - float velocity; - - if (params->m_fDistance >= SQR(SOUND_INTENSITY)) - return false; - - automobile = (CAutomobile *)params->m_pVehicle; - CalculateDistance(params->m_bDistanceCalculated, params->m_fDistance); - for (int32 i = 0; i < ARRAY_SIZE(automobile->Doors); i++) { - if (automobile->Damage.GetDoorStatus(i) == DOOR_STATUS_SWINGING) { - doorState = automobile->Doors[i].m_nDoorState; - if (doorState == DOOR_STATUS_SMASHED || doorState == DOOR_STATUS_SWINGING) { - velocity = Min(0.3f, Abs(automobile->Doors[i].m_fAngVel)); - if (velocity > 0.0035f) { - emittingVol = (100.f * velocity * 10.f / 3.f); - m_sQueueSample.m_nVolume = ComputeVolume(emittingVol, SOUND_INTENSITY, m_sQueueSample.m_fDistance); - if (m_sQueueSample.m_nVolume) { - m_sQueueSample.m_nCounter = i + 6; - m_sQueueSample.m_nSampleIndex = m_anRandomTable[1] % 6 + SFX_COL_CAR_PANEL_1; - m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(m_sQueueSample.m_nSampleIndex) + RandomDisplacement(1000); - m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; - m_sQueueSample.m_bIs2D = false; - m_sQueueSample.m_nReleasingVolumeModificator = 10; - m_sQueueSample.m_nLoopCount = 1; - m_sQueueSample.m_nEmittingVolume = emittingVol; - m_sQueueSample.m_nLoopStart = 0; - m_sQueueSample.m_nLoopEnd = -1; - m_sQueueSample.m_fSpeedMultiplier = 1.0f; - m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY; - m_sQueueSample.m_bReleasingSoundFlag = true; - m_sQueueSample.m_bReverbFlag = true; - m_sQueueSample.m_bRequireReflection = true; - AddSampleToRequestedQueue(); - } - } - } - } - } - return true; -} - -void -cAudioManager::ProcessVehicleEngine(cVehicleParams *params) -{ - const float SOUND_INTENSITY = 50.0f; - - CVehicle *playerVeh; - CVehicle *veh; - CAutomobile *automobile; - float relativeGearChange; - float relativeChange; - uint8 volume; - int32 freq = 0; // uinitialized variable - uint8 emittingVol; - cTransmission *transmission; - uint8 currentGear; - float modificator; - float traction = 0.f; - - if (params->m_fDistance < SQR(SOUND_INTENSITY)) { - playerVeh = FindPlayerVehicle(); - veh = params->m_pVehicle; - if (playerVeh == veh && veh->GetStatus() == STATUS_WRECKED) { - SampleManager.StopChannel(m_nActiveSamples); - return; - } - if (veh->bEngineOn) { - CalculateDistance(params->m_bDistanceCalculated, params->m_fDistance); - automobile = (CAutomobile *)params->m_pVehicle; - if (params->m_nIndex == DODO) { - ProcessCesna(params); - return; - } - if (FindPlayerVehicle() == veh) { - ProcessPlayersVehicleEngine(params, automobile); - return; - } - transmission = params->m_pTransmission; - if (transmission) { - currentGear = params->m_pVehicle->m_nCurrentGear; - if (automobile->m_nWheelsOnGround) { - if (automobile->bIsHandbrakeOn) { - if (params->m_fVelocityChange == 0.0f) - traction = 0.9f; - } else if (params->m_pVehicle->GetStatus() == STATUS_SIMPLE) { - traction = 0.0f; - } else { - switch (transmission->nDriveType) { - case '4': - for (int32 i = 0; i < ARRAY_SIZE(automobile->m_aWheelState); i++) { - if (automobile->m_aWheelState[i] == WHEEL_STATE_SPINNING) - traction += 0.05f; - } - break; - case 'F': - if (automobile->m_aWheelState[0] == WHEEL_STATE_SPINNING) - traction += 0.1f; - if (automobile->m_aWheelState[2] == WHEEL_STATE_SPINNING) - traction += 0.1f; - break; - case 'R': - if (automobile->m_aWheelState[1] == WHEEL_STATE_SPINNING) - traction += 0.1f; - if (automobile->m_aWheelState[3] == WHEEL_STATE_SPINNING) - traction += 0.1f; - break; - } - } - if (transmission->fMaxVelocity <= 0.f) { - relativeChange = 0.f; - } else if (currentGear) { - relativeGearChange = - Min(1.0f, (params->m_fVelocityChange - transmission->Gears[currentGear].fShiftDownVelocity) / transmission->fMaxVelocity * 2.5f); - if (traction == 0.0f && automobile->GetStatus() != STATUS_SIMPLE && - params->m_fVelocityChange >= transmission->Gears[1].fShiftUpVelocity) { - traction = 0.7f; - } - relativeChange = traction * automobile->m_fGasPedalAudio * 0.95f + (1.0f - traction) * relativeGearChange; - } else - relativeChange = - Min(1.0f, 1.0f - Abs((params->m_fVelocityChange - transmission->Gears[0].fShiftDownVelocity) / transmission->fMaxReverseVelocity)); - } else { - if (automobile->m_nDriveWheelsOnGround) - automobile->m_fGasPedalAudio *= 0.4f; - relativeChange = automobile->m_fGasPedalAudio; - } - modificator = relativeChange; - if (currentGear || !automobile->m_nWheelsOnGround) - freq = 1200 * currentGear + 18000.f * modificator + 14000; - else - freq = 13000.f * modificator + 14000; - if (modificator >= 0.75f) { - emittingVol = 120; - volume = ComputeVolume(emittingVol, SOUND_INTENSITY, m_sQueueSample.m_fDistance); - } else { - emittingVol = modificator * 4.0f / 3.0f * 40.f + 80.f; - volume = ComputeVolume(emittingVol, SOUND_INTENSITY, m_sQueueSample.m_fDistance); - } - } else { - modificator = 0.f; - emittingVol = 80; - volume = ComputeVolume(emittingVol, SOUND_INTENSITY, m_sQueueSample.m_fDistance); - } - m_sQueueSample.m_nVolume = volume; - if (m_sQueueSample.m_nVolume) { - if (automobile->GetStatus() == STATUS_SIMPLE) { - if (modificator < 0.02f) { - m_sQueueSample.m_nSampleIndex = aVehicleSettings[params->m_nIndex].m_bEngineSoundType - 1 + SFX_CAR_IDLE_1; - freq = modificator * 10000 + 22050; - m_sQueueSample.m_nCounter = 52; - } else { - m_sQueueSample.m_nSampleIndex = aVehicleSettings[params->m_nIndex].m_nAccelerationSampleIndex; - m_sQueueSample.m_nCounter = 2; - } - } else { - if (automobile->m_fGasPedal < 0.05f) { - m_sQueueSample.m_nSampleIndex = aVehicleSettings[params->m_nIndex].m_bEngineSoundType - 1 + SFX_CAR_IDLE_1; - freq = modificator * 10000 + 22050; - m_sQueueSample.m_nCounter = 52; - } else { - m_sQueueSample.m_nSampleIndex = aVehicleSettings[params->m_nIndex].m_nAccelerationSampleIndex; - m_sQueueSample.m_nCounter = 2; - } - } - m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; - m_sQueueSample.m_bIs2D = false; - m_sQueueSample.m_nReleasingVolumeModificator = 3; - m_sQueueSample.m_nFrequency = freq + 100 * m_sQueueSample.m_nEntityIndex % 1000; - if (m_sQueueSample.m_nSampleIndex == SFX_CAR_IDLE_6 || m_sQueueSample.m_nSampleIndex == SFX_CAR_REV_6) - m_sQueueSample.m_nFrequency /= 2; - m_sQueueSample.m_nLoopCount = 0; - m_sQueueSample.m_nEmittingVolume = emittingVol; - m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex); - m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex); - m_sQueueSample.m_fSpeedMultiplier = 6.0f; - m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY; - m_sQueueSample.m_bReleasingSoundFlag = false; - m_sQueueSample.m_nReleasingVolumeDivider = 8; - m_sQueueSample.m_bReverbFlag = true; - m_sQueueSample.m_bRequireReflection = false; - AddSampleToRequestedQueue(); - } - } - } -} - -void -cAudioManager::ProcessVehicleHorn(cVehicleParams *params) -{ - const float SOUND_INTENSITY = 40.0f; - - CAutomobile *automobile; - - if (params->m_fDistance < SQR(SOUND_INTENSITY)) { - automobile = (CAutomobile *)params->m_pVehicle; - if ((!automobile->m_bSirenOrAlarm || !UsesSirenSwitching(params->m_nIndex)) && automobile->GetModelIndex() != MI_MRWHOOP) { - if (automobile->m_nCarHornTimer) { - if (params->m_pVehicle->GetStatus() != STATUS_PLAYER) { - automobile->m_nCarHornTimer = Min(44, automobile->m_nCarHornTimer); - if (automobile->m_nCarHornTimer == 44) - automobile->m_nCarHornPattern = (m_FrameCounter + m_sQueueSample.m_nEntityIndex) & 7; - if (!hornPatternsArray[automobile->m_nCarHornPattern][44 - automobile->m_nCarHornTimer]) - return; - } - - CalculateDistance(params->m_bDistanceCalculated, params->m_fDistance); - m_sQueueSample.m_nVolume = ComputeVolume(80, SOUND_INTENSITY, m_sQueueSample.m_fDistance); - if (m_sQueueSample.m_nVolume) { - m_sQueueSample.m_nCounter = 4; - m_sQueueSample.m_nSampleIndex = aVehicleSettings[params->m_nIndex].m_nHornSample; - m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; - m_sQueueSample.m_bIs2D = false; - m_sQueueSample.m_nReleasingVolumeModificator = 2; - m_sQueueSample.m_nFrequency = aVehicleSettings[params->m_nIndex].m_nHornFrequency; - m_sQueueSample.m_nLoopCount = 0; - m_sQueueSample.m_nEmittingVolume = 80; - m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex); - m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex); - m_sQueueSample.m_fSpeedMultiplier = 5.0f; - m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY; - m_sQueueSample.m_bReleasingSoundFlag = false; - m_sQueueSample.m_nReleasingVolumeDivider = 3; - m_sQueueSample.m_bReverbFlag = true; - m_sQueueSample.m_bRequireReflection = false; - AddSampleToRequestedQueue(); - } - } - } - } -} - -void -cAudioManager::ProcessVehicleOneShots(cVehicleParams *params) -{ - int16 event; - uint8 emittingVol; - float relVol; - float vol; - bool noReflections; - float maxDist; - cPedParams pedParams; - - static uint8 WaveIndex = 41; - static uint8 GunIndex = 53; - static uint8 iWheelIndex = 82; - static uint8 CrunchOffset = 0; - - for (int i = 0; i < m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_AudioEvents; i++) { - noReflections = 0; - m_sQueueSample.m_bRequireReflection = false; - event = m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_awAudioEvent[i]; - switch (event) { - case SOUND_CAR_DOOR_CLOSE_BONNET: - case SOUND_CAR_DOOR_CLOSE_BUMPER: - case SOUND_CAR_DOOR_CLOSE_FRONT_LEFT: - case SOUND_CAR_DOOR_CLOSE_FRONT_RIGHT: - case SOUND_CAR_DOOR_CLOSE_BACK_LEFT: - case SOUND_CAR_DOOR_CLOSE_BACK_RIGHT: - { - const float SOUND_INTENSITY = 50.0f; - maxDist = SQR(SOUND_INTENSITY); - emittingVol = m_anRandomTable[2] % 5 + 122; - switch (aVehicleSettings[params->m_nIndex].m_bDoorType) { - case 0: - m_sQueueSample.m_nSampleIndex = SFX_OLD_CAR_DOOR_CLOSE; - break; - case 2: - m_sQueueSample.m_nSampleIndex = SFX_TRUCK_DOOR_CLOSE; - break; - case 3: - m_sQueueSample.m_nSampleIndex = SFX_AIR_BRAKES; - break; - default: - m_sQueueSample.m_nSampleIndex = SFX_NEW_CAR_DOOR_CLOSE; - break; - } - m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; - m_sQueueSample.m_nCounter = m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_awAudioEvent[i] + 22; - m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(m_sQueueSample.m_nSampleIndex); - m_sQueueSample.m_nFrequency += RandomDisplacement(m_sQueueSample.m_nFrequency / 32); - m_sQueueSample.m_nReleasingVolumeModificator = 3; - m_sQueueSample.m_fSpeedMultiplier = 0.0f; - m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY; - m_sQueueSample.m_bRequireReflection = true; - break; - } - case SOUND_CAR_DOOR_OPEN_BONNET: - case SOUND_CAR_DOOR_OPEN_BUMPER: - case SOUND_CAR_DOOR_OPEN_FRONT_LEFT: - case SOUND_CAR_DOOR_OPEN_FRONT_RIGHT: - case SOUND_CAR_DOOR_OPEN_BACK_LEFT: - case SOUND_CAR_DOOR_OPEN_BACK_RIGHT: - { - const float SOUND_INTENSITY = 50.0f; - maxDist = SQR(SOUND_INTENSITY); - emittingVol = m_anRandomTable[1] % 10 + 117; - switch (aVehicleSettings[params->m_nIndex].m_bDoorType) { - case 0: - m_sQueueSample.m_nSampleIndex = SFX_OLD_CAR_DOOR_OPEN; - break; - case 2: - m_sQueueSample.m_nSampleIndex = SFX_TRUCK_DOOR_OPEN; - break; - case 3: - m_sQueueSample.m_nSampleIndex = SFX_AIR_BRAKES; - break; - default: - m_sQueueSample.m_nSampleIndex = SFX_NEW_CAR_DOOR_OPEN; - break; - } - m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; - m_sQueueSample.m_nCounter = m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_awAudioEvent[i] + 10; - m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(m_sQueueSample.m_nSampleIndex); - m_sQueueSample.m_nFrequency += RandomDisplacement(m_sQueueSample.m_nFrequency / 32); - m_sQueueSample.m_nReleasingVolumeModificator = 3; - m_sQueueSample.m_fSpeedMultiplier = 0.0f; - m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY; - m_sQueueSample.m_bRequireReflection = true; - break; - } - case SOUND_CAR_WINDSHIELD_CRACK: - { - const float SOUND_INTENSITY = 30.0f; - maxDist = SQR(SOUND_INTENSITY); - m_sQueueSample.m_nSampleIndex = SFX_GLASS_CRACK; - m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; - m_sQueueSample.m_nCounter = 68; - emittingVol = m_anRandomTable[1] % 30 + 60; - m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_GLASS_CRACK); - m_sQueueSample.m_nReleasingVolumeModificator = 5; - m_sQueueSample.m_fSpeedMultiplier = 0.0f; - m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY; - } break; - case SOUND_CAR_JUMP: - { - const float SOUND_INTENSITY = 35.0f; - emittingVol = Max(80.f, 2 * (100.f * m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_afVolume[i])); - maxDist = SQR(SOUND_INTENSITY); - m_sQueueSample.m_nSampleIndex = SFX_TYRE_BUMP; - m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; - m_sQueueSample.m_nCounter = iWheelIndex++; - if (iWheelIndex > 85) - iWheelIndex = 82; - m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_TYRE_BUMP); - m_sQueueSample.m_nFrequency += RandomDisplacement(m_sQueueSample.m_nFrequency / 16); - if (params->m_nIndex == 41) { - m_sQueueSample.m_nFrequency *= 2; - emittingVol /= 2; - } - m_sQueueSample.m_nReleasingVolumeModificator = 6; - m_sQueueSample.m_fSpeedMultiplier = 2.0f; - m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY; - break; - } - case SOUND_CAR_ENGINE_START: - { - const float SOUND_INTENSITY = 40.0f; - emittingVol = 60; - maxDist = SQR(SOUND_INTENSITY); - m_sQueueSample.m_nSampleIndex = SFX_CAR_STARTER; - m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; - m_sQueueSample.m_nCounter = 33; - m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_CAR_STARTER); - m_sQueueSample.m_nReleasingVolumeModificator = 1; - m_sQueueSample.m_fSpeedMultiplier = 2.0f; - m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY; - m_sQueueSample.m_bRequireReflection = true; - break; - } - case SOUND_CAR_LIGHT_BREAK: - { - const float SOUND_INTENSITY = 30.0f; - m_sQueueSample.m_nSampleIndex = SFX_GLASS_SHARD_1; - m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; - m_sQueueSample.m_nCounter = 37; - m_sQueueSample.m_nFrequency = 9 * SampleManager.GetSampleBaseFrequency(SFX_GLASS_SHARD_1) / 10; - m_sQueueSample.m_nFrequency += RandomDisplacement(m_sQueueSample.m_nFrequency / 8); - m_sQueueSample.m_nReleasingVolumeModificator = 5; - m_sQueueSample.m_fSpeedMultiplier = 0.0f; - m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY; - maxDist = SQR(SOUND_INTENSITY); - emittingVol = m_anRandomTable[4] % 10 + 30; - break; - } - case SOUND_CAR_HYDRAULIC_1: - case SOUND_CAR_HYDRAULIC_2: - { - const float SOUND_INTENSITY = 35.0f; - if (event == MOONBEAM) // todo check - m_sQueueSample.m_nFrequency = 15600; - else - m_sQueueSample.m_nFrequency = 13118; - m_sQueueSample.m_nSampleIndex = SFX_SUSPENSION_FAST_MOVE; - m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; - m_sQueueSample.m_nCounter = 51; - m_sQueueSample.m_nFrequency += RandomDisplacement(m_sQueueSample.m_nFrequency / 8); - m_sQueueSample.m_nReleasingVolumeModificator = 5; - m_sQueueSample.m_fSpeedMultiplier = 0.0f; - m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY; - maxDist = SQR(SOUND_INTENSITY); - emittingVol = m_anRandomTable[0] % 15 + 55; - break; - } - case SOUND_CAR_HYDRAULIC_3: - { - const float SOUND_INTENSITY = 35.0f; - m_sQueueSample.m_nSampleIndex = SFX_SUSPENSION_SLOW_MOVE_LOOP; - m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; - m_sQueueSample.m_nCounter = 86; - m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_SUSPENSION_SLOW_MOVE_LOOP); - m_sQueueSample.m_nReleasingVolumeModificator = 5; - m_sQueueSample.m_fSpeedMultiplier = 0.0f; - m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY; - m_sQueueSample.m_nReleasingVolumeDivider = 7; - noReflections = true; - maxDist = SQR(SOUND_INTENSITY); - emittingVol = m_anRandomTable[0] % 15 + 55; - break; - } - case SOUND_CAR_JERK: - { - const float SOUND_INTENSITY = 35.0f; - m_sQueueSample.m_nSampleIndex = SFX_SHAG_SUSPENSION; - m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; - m_sQueueSample.m_nCounter = 87; - m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_SHAG_SUSPENSION); - m_sQueueSample.m_nFrequency += RandomDisplacement(m_sQueueSample.m_nFrequency / 8); - m_sQueueSample.m_nReleasingVolumeModificator = 5; - m_sQueueSample.m_fSpeedMultiplier = 0.0f; - m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY; - maxDist = SQR(SOUND_INTENSITY); - emittingVol = m_anRandomTable[1] % 15 + 55; - break; - } - case SOUND_CAR_SPLASH: - { - const float SOUND_INTENSITY = 40.0f; - vol = m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_afVolume[i]; - if (vol <= 300.f) - continue; - if (vol > 1200.f) - m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_afVolume[i] = 1200.0f; - relVol = (m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_afVolume[i] - 300.f) / 900.f; - m_sQueueSample.m_nSampleIndex = (m_anRandomTable[0] & 1) + SFX_BOAT_SPLASH_1; - m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; - m_sQueueSample.m_nCounter = WaveIndex++; - if (WaveIndex > 46) - WaveIndex = 41; - m_sQueueSample.m_nFrequency = (7000.f * relVol) + 6000; - m_sQueueSample.m_nReleasingVolumeModificator = 3; - m_sQueueSample.m_fSpeedMultiplier = 2.0f; - m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY; - emittingVol = (55.f * relVol); - maxDist = SQR(SOUND_INTENSITY); - break; - } - case SOUND_17: - { - const float SOUND_INTENSITY = 50.0f; - m_sQueueSample.m_nSampleIndex = SFX_POLICE_BOAT_THUMB_OFF; - m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; - m_sQueueSample.m_nCounter = 47; - m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_POLICE_BOAT_THUMB_OFF) + RandomDisplacement(600); - m_sQueueSample.m_nReleasingVolumeModificator = 2; - m_sQueueSample.m_fSpeedMultiplier = 0.0f; - m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY; - emittingVol = m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_afVolume[i]; - maxDist = SQR(SOUND_INTENSITY); - break; - } - case SOUND_18: - case SOUND_19: - { - const float SOUND_INTENSITY = 35.0f; - m_sQueueSample.m_nSampleIndex = SFX_AIR_BRAKES; - m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; - m_sQueueSample.m_nCounter = 59; - m_sQueueSample.m_nFrequency = RandomDisplacement(1000) + 11025; - m_sQueueSample.m_nReleasingVolumeModificator = 5; - m_sQueueSample.m_fSpeedMultiplier = 5.0f; - m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY; - maxDist = SQR(SOUND_INTENSITY); - emittingVol = m_anRandomTable[1] % 20 + 70; - break; - } - case SOUND_CAR_TANK_TURRET_ROTATE: - { - const float SOUND_INTENSITY = 40.0f; - vol = m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_afVolume[i]; - if (vol > 96.0f / 2500.0f) - vol = 96.0f / 2500.0f; - m_sQueueSample.m_nSampleIndex = SFX_TANK_TURRET; - m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; - m_sQueueSample.m_nCounter = 79; - m_sQueueSample.m_nFrequency = (3000.f * vol * 2500.0f / 96.0f) + 9000; - m_sQueueSample.m_nReleasingVolumeModificator = 2; - m_sQueueSample.m_fSpeedMultiplier = 2.0f; - m_sQueueSample.m_nReleasingVolumeDivider = 3; - m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY; - emittingVol = (37.f * vol * 2500.0f / 96.0f) + 90; - maxDist = SQR(SOUND_INTENSITY); - noReflections = true; - break; - } - case SOUND_CAR_BOMB_TICK: - { - const float SOUND_INTENSITY = 30.0f; - m_sQueueSample.m_nSampleIndex = SFX_BOMB_BEEP; - m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; - m_sQueueSample.m_nCounter = 80; - m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_BOMB_BEEP); - m_sQueueSample.m_nReleasingVolumeModificator = 3; - m_sQueueSample.m_fSpeedMultiplier = 0.0f; - m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY; - maxDist = SQR(SOUND_INTENSITY); - m_sQueueSample.m_bRequireReflection = true; - emittingVol = 60; - break; - } - case SOUND_PLANE_ON_GROUND: - { - const float SOUND_INTENSITY = 180.0f; - m_sQueueSample.m_nSampleIndex = SFX_JUMBO_LAND_WHEELS; - m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; - m_sQueueSample.m_nCounter = 81; - m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_JUMBO_LAND_WHEELS); - m_sQueueSample.m_nReleasingVolumeModificator = 2; - m_sQueueSample.m_fSpeedMultiplier = 0.0f; - m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY; - maxDist = SQR(SOUND_INTENSITY); - emittingVol = m_anRandomTable[4] % 25 + 75; - break; - } - case SOUND_WEAPON_SHOT_FIRED: - { - const float SOUND_INTENSITY = 120.0f; - emittingVol = m_anRandomTable[2]; - maxDist = SQR(SOUND_INTENSITY); - m_sQueueSample.m_nSampleIndex = SFX_UZI_LEFT; - m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; - m_sQueueSample.m_nCounter = GunIndex++; - emittingVol = emittingVol % 15 + 65; - if (GunIndex > 58) - GunIndex = 53; - m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_UZI_LEFT); - m_sQueueSample.m_nFrequency += RandomDisplacement(m_sQueueSample.m_nFrequency / 16); - m_sQueueSample.m_nReleasingVolumeModificator = 3; - m_sQueueSample.m_fSpeedMultiplier = 0.0f; - m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY; - break; - } - case SOUND_WEAPON_HIT_VEHICLE: - { - const float SOUND_INTENSITY = 40.0f; - m_sQueueSample.m_nSampleIndex = m_anRandomTable[m_sQueueSample.m_nEntityIndex % ARRAY_SIZE(m_anRandomTable)] % 6 + SFX_BULLET_CAR_1; - m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; - m_sQueueSample.m_nCounter = 34; - m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(m_sQueueSample.m_nSampleIndex); - m_sQueueSample.m_nFrequency += RandomDisplacement(m_sQueueSample.m_nFrequency / 32); - m_sQueueSample.m_nReleasingVolumeModificator = 7; - m_sQueueSample.m_fSpeedMultiplier = 0.0f; - m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY; - maxDist = SQR(SOUND_INTENSITY); - emittingVol = m_anRandomTable[3] % 20 + 90; - break; - } - case SOUND_BOMB_TIMED_ACTIVATED: - case SOUND_55: - case SOUND_BOMB_ONIGNITION_ACTIVATED: - case SOUND_BOMB_TICK: - { - const float SOUND_INTENSITY = 50.0f; - m_sQueueSample.m_nSampleIndex = SFX_ARM_BOMB; - m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; - m_sQueueSample.m_nCounter = 36; - m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_ARM_BOMB); - m_sQueueSample.m_nReleasingVolumeModificator = 0; - m_sQueueSample.m_fSpeedMultiplier = 0.0f; - m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY; - m_sQueueSample.m_bRequireReflection = true; - emittingVol = 50; - maxDist = SQR(SOUND_INTENSITY); - break; - } - case SOUND_PED_HELI_PLAYER_FOUND: - pedParams.m_pPed = nil; - pedParams.m_bDistanceCalculated = false; - pedParams.m_fDistance = 0.0f; - pedParams.m_bDistanceCalculated = params->m_bDistanceCalculated; - pedParams.m_fDistance = params->m_fDistance; - SetupPedComments(&pedParams, SOUND_PED_HELI_PLAYER_FOUND); - continue; - case SOUND_PED_BODYCAST_HIT: - pedParams.m_pPed = nil; - pedParams.m_bDistanceCalculated = false; - pedParams.m_fDistance = 0.0f; - pedParams.m_bDistanceCalculated = params->m_bDistanceCalculated; - pedParams.m_fDistance = params->m_fDistance; - SetupPedComments(&pedParams, SOUND_PED_BODYCAST_HIT); - continue; - case SOUND_WATER_FALL: - { - const float SOUND_INTENSITY = 40.0f; - m_sQueueSample.m_nSampleIndex = SFX_SPLASH_1; - m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; - m_sQueueSample.m_nCounter = 15; - m_sQueueSample.m_nFrequency = RandomDisplacement(1000) + 16000; - m_sQueueSample.m_nReleasingVolumeModificator = 1; - m_sQueueSample.m_fSpeedMultiplier = 0.0f; - m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY; - maxDist = SQR(SOUND_INTENSITY); - m_sQueueSample.m_bRequireReflection = true; - emittingVol = m_anRandomTable[4] % 20 + 90; - break; - } - case SOUND_SPLATTER: - { - const float SOUND_INTENSITY = 40.0f; - m_sQueueSample.m_nSampleIndex = CrunchOffset + SFX_PED_CRUNCH_1; - m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; - m_sQueueSample.m_nCounter = 48; - m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_PED_CRUNCH_1) + RandomDisplacement(600); - m_sQueueSample.m_nReleasingVolumeModificator = 1; - m_sQueueSample.m_fSpeedMultiplier = 0.0f; - m_sQueueSample.m_fSoundIntensity = 40.0f; - ++CrunchOffset; - maxDist = SQR(SOUND_INTENSITY); - emittingVol = m_anRandomTable[4] % 20 + 55; - CrunchOffset %= 2; - m_sQueueSample.m_bRequireReflection = true; - break; - } - case SOUND_CAR_PED_COLLISION: - { - const float SOUND_INTENSITY = 40.0f; - vol = Min(20.0f, m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_afVolume[i]); - emittingVol = (vol / 20.0f * 127.f); - if (!emittingVol) - continue; - - m_sQueueSample.m_nSampleIndex = (m_anRandomTable[2] & 3) + SFX_FIGHT_1; - m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; - m_sQueueSample.m_nCounter = 50; - m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(m_sQueueSample.m_nSampleIndex) / 2; - m_sQueueSample.m_nReleasingVolumeModificator = 1; - m_sQueueSample.m_fSpeedMultiplier = 0.0f; - m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY; - maxDist = SQR(SOUND_INTENSITY); - break; - } - default: - continue; - } - if (params->m_fDistance < maxDist) { - CalculateDistance(params->m_bDistanceCalculated, params->m_fDistance); - m_sQueueSample.m_nVolume = ComputeVolume(emittingVol, m_sQueueSample.m_fSoundIntensity, m_sQueueSample.m_fDistance); - if (m_sQueueSample.m_nVolume != 0) { - if (noReflections) { - m_sQueueSample.m_nLoopCount = 0; - m_sQueueSample.m_bReleasingSoundFlag = false; - } else { - m_sQueueSample.m_nLoopCount = 1; - m_sQueueSample.m_bReleasingSoundFlag = true; - } - m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex); - m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex); - m_sQueueSample.m_nEmittingVolume = emittingVol; - m_sQueueSample.m_bReverbFlag = true; - m_sQueueSample.m_bIs2D = false; - AddSampleToRequestedQueue(); - } - } - } -} - -bool -cAudioManager::ProcessVehicleReverseWarning(cVehicleParams *params) -{ - const float SOUND_INTENSITY = 50.0f; - - CVehicle *veh = params->m_pVehicle; - - if (params->m_fDistance >= SQR(SOUND_INTENSITY)) - return false; - - if (veh->bEngineOn && veh->m_fGasPedal < 0.0f) { - CalculateDistance(params->m_bDistanceCalculated, params->m_fDistance); - m_sQueueSample.m_nVolume = ComputeVolume(60, SOUND_INTENSITY, m_sQueueSample.m_fDistance); - if (m_sQueueSample.m_nVolume) { - m_sQueueSample.m_nCounter = 12; - m_sQueueSample.m_nSampleIndex = SFX_REVERSE_WARNING; - m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; - m_sQueueSample.m_bIs2D = false; - m_sQueueSample.m_nReleasingVolumeModificator = 2; - m_sQueueSample.m_nFrequency = (100 * m_sQueueSample.m_nEntityIndex & 1023) + SampleManager.GetSampleBaseFrequency(SFX_REVERSE_WARNING); - m_sQueueSample.m_nLoopCount = 0; - m_sQueueSample.m_nEmittingVolume = 60; - m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex); - m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex); - m_sQueueSample.m_fSpeedMultiplier = 3.0f; - m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY; - m_sQueueSample.m_bReleasingSoundFlag = false; - m_sQueueSample.m_nReleasingVolumeDivider = 3; - m_sQueueSample.m_bReverbFlag = true; - m_sQueueSample.m_bRequireReflection = false; - AddSampleToRequestedQueue(); - } - } - return true; -} - -bool -cAudioManager::ProcessVehicleRoadNoise(cVehicleParams *params) -{ - const float SOUND_INTENSITY = 95.0f; - - int32 emittingVol; - uint32 freq; - float modificator; - int sampleFreq; - float velocity; - - if (params->m_fDistance >= SQR(SOUND_INTENSITY)) - return false; - if (params->m_pTransmission) { - if (params->m_pVehicle->m_vecMoveSpeed.z) { - velocity = Abs(params->m_fVelocityChange); - if (velocity > 0.0f) { - CalculateDistance(params->m_bDistanceCalculated, params->m_fDistance); - emittingVol = 30.f * Min(1.f, velocity / (0.5f * params->m_pTransmission->fMaxVelocity)); - m_sQueueSample.m_nVolume = ComputeVolume(emittingVol, SOUND_INTENSITY, m_sQueueSample.m_fDistance); - if (m_sQueueSample.m_nVolume) { - m_sQueueSample.m_nCounter = 0; - m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; - m_sQueueSample.m_bIs2D = false; - m_sQueueSample.m_nReleasingVolumeModificator = 3; - if (params->m_pVehicle->m_nSurfaceTouched == SURFACE_PUDDLE) { - m_sQueueSample.m_nSampleIndex = SFX_BOAT_WATER_LOOP; - freq = 6050 * emittingVol / 30 + 16000; - } else { - m_sQueueSample.m_nSampleIndex = SFX_ROAD_NOISE; - modificator = m_sQueueSample.m_fDistance / 190.f; - sampleFreq = SampleManager.GetSampleBaseFrequency(SFX_ROAD_NOISE); - freq = (sampleFreq * modificator) + ((3 * sampleFreq) / 4); - } - m_sQueueSample.m_nFrequency = freq; - m_sQueueSample.m_nLoopCount = 0; - m_sQueueSample.m_nEmittingVolume = emittingVol; - m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex); - m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex); - m_sQueueSample.m_fSpeedMultiplier = 6.0f; - m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY; - m_sQueueSample.m_bReleasingSoundFlag = false; - m_sQueueSample.m_nReleasingVolumeDivider = 4; - m_sQueueSample.m_bReverbFlag = true; - m_sQueueSample.m_bRequireReflection = false; - AddSampleToRequestedQueue(); - } - } - } - } - return true; -} - -void -cAudioManager::ProcessVehicleSirenOrAlarm(cVehicleParams *params) -{ - const float SOUND_INTENSITY = 110.0f; - - if (params->m_fDistance < SQR(SOUND_INTENSITY)) { - CVehicle *veh = params->m_pVehicle; - if (veh->m_bSirenOrAlarm == 0 && veh->m_nAlarmState <= 0) - return; - -#ifdef FIX_BUGS - if (params->m_pVehicle->GetStatus() == STATUS_WRECKED) - return; -#endif - CalculateDistance(params->m_bDistanceCalculated, params->m_fDistance); - m_sQueueSample.m_nVolume = ComputeVolume(80, SOUND_INTENSITY, m_sQueueSample.m_fDistance); - if (m_sQueueSample.m_nVolume) { - m_sQueueSample.m_nCounter = 5; - if (UsesSiren(params->m_nIndex)) { - if (params->m_pVehicle->GetStatus() == STATUS_ABANDONED) - return; - if (veh->m_nCarHornTimer && params->m_nIndex != FIRETRUK) { - m_sQueueSample.m_nSampleIndex = SFX_SIREN_FAST; - if (params->m_nIndex == FBICAR) - m_sQueueSample.m_nFrequency = 16113; - else - m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_SIREN_FAST); - m_sQueueSample.m_nCounter = 60; - } else { - m_sQueueSample.m_nSampleIndex = aVehicleSettings[params->m_nIndex].m_nSirenOrAlarmSample; - m_sQueueSample.m_nFrequency = aVehicleSettings[params->m_nIndex].m_nSirenOrAlarmFrequency; - } - } else { - m_sQueueSample.m_nSampleIndex = aVehicleSettings[params->m_nIndex].m_nSirenOrAlarmSample; - m_sQueueSample.m_nFrequency = aVehicleSettings[params->m_nIndex].m_nSirenOrAlarmFrequency; - } - m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; - m_sQueueSample.m_bIs2D = false; - m_sQueueSample.m_nReleasingVolumeModificator = 1; - m_sQueueSample.m_nLoopCount = 0; - m_sQueueSample.m_nEmittingVolume = 80; - m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex); - m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex); - m_sQueueSample.m_fSpeedMultiplier = 7.0f; - m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY; - m_sQueueSample.m_bReleasingSoundFlag = false; - m_sQueueSample.m_nReleasingVolumeDivider = 5; - m_sQueueSample.m_bReverbFlag = true; - m_sQueueSample.m_bRequireReflection = false; - AddSampleToRequestedQueue(); - return; - } - } -} - -void -cAudioManager::ProcessVehicleSkidding(cVehicleParams *params) -{ - const float SOUND_INTENSITY = 40.0f; - - CAutomobile *automobile; - cTransmission *transmission; - int32 emittingVol; - float newSkidVal = 0.0f; - float skidVal = 0.0f; - - if (params->m_fDistance >= SQR(SOUND_INTENSITY)) - return; - automobile = (CAutomobile *)params->m_pVehicle; - if (!automobile->m_nWheelsOnGround) - return; - CalculateDistance(params->m_bDistanceCalculated, params->m_fDistance); - for (int32 i = 0; i < ARRAY_SIZE(automobile->m_aWheelState); i++) { - if (automobile->m_aWheelState[i] == WHEEL_STATE_NORMAL || automobile->Damage.GetWheelStatus(i) == WHEEL_STATUS_MISSING) - continue; - transmission = params->m_pTransmission; - switch (transmission->nDriveType) - { - case '4': - newSkidVal = GetVehicleDriveWheelSkidValue(i, automobile, transmission, params->m_fVelocityChange); - break; - case 'F': - if (i == CARWHEEL_FRONT_LEFT || i == CARWHEEL_FRONT_RIGHT) - newSkidVal = GetVehicleDriveWheelSkidValue(i, automobile, transmission, params->m_fVelocityChange); - else - newSkidVal = GetVehicleNonDriveWheelSkidValue(i, automobile, transmission, params->m_fVelocityChange); - break; - case 'R': - if (i == CARWHEEL_REAR_LEFT || i == CARWHEEL_REAR_RIGHT) - newSkidVal = GetVehicleDriveWheelSkidValue(i, automobile, transmission, params->m_fVelocityChange); - else - newSkidVal = GetVehicleNonDriveWheelSkidValue(i, automobile, transmission, params->m_fVelocityChange); - break; - default: - break; - } - skidVal = Max(skidVal, newSkidVal); - } - - if (skidVal > 0.0f) { - emittingVol = 50.f * skidVal; - m_sQueueSample.m_nVolume = ComputeVolume(emittingVol, SOUND_INTENSITY, m_sQueueSample.m_fDistance); - if (m_sQueueSample.m_nVolume != 0) { - m_sQueueSample.m_nCounter = 3; - switch (params->m_pVehicle->m_nSurfaceTouched) { - case SURFACE_GRASS: - case SURFACE_HEDGE: - m_sQueueSample.m_nSampleIndex = SFX_RAIN; - emittingVol /= 4; - m_sQueueSample.m_nFrequency = 13000.f * skidVal + 35000.f; - m_sQueueSample.m_nVolume /= 4; - break; - case SURFACE_DIRT: - case SURFACE_DIRTTRACK: - case SURFACE_SAND: - case SURFACE_PUDDLE: - m_sQueueSample.m_nSampleIndex = SFX_GRAVEL_SKID; - m_sQueueSample.m_nFrequency = 6000.f * skidVal + 10000.f; - break; - - default: - m_sQueueSample.m_nSampleIndex = SFX_SKID; - m_sQueueSample.m_nFrequency = 5000.f * skidVal + 11000.f; - break; - } - - m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; - m_sQueueSample.m_bIs2D = false; - m_sQueueSample.m_nReleasingVolumeModificator = 8; - m_sQueueSample.m_nLoopCount = 0; - m_sQueueSample.m_nEmittingVolume = emittingVol; - m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex); - m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex); - m_sQueueSample.m_fSpeedMultiplier = 3.0f; - m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY; - m_sQueueSample.m_bReleasingSoundFlag = false; - m_sQueueSample.m_nReleasingVolumeDivider = 3; - m_sQueueSample.m_bReverbFlag = true; - m_sQueueSample.m_bRequireReflection = false; - AddSampleToRequestedQueue(); - } - } -} - -void cAudioManager::ProcessWaterCannon(int32) -{ - const float SOUND_INTENSITY = 900.0f; - - for (int32 i = 0; i < NUM_WATERCANNONS; i++) { - if (CWaterCannons::aCannons[i].m_nId) { - m_sQueueSample.m_vecPos = CWaterCannons::aCannons[0].m_avecPos[CWaterCannons::aCannons[i].m_nCur]; - float distSquared = GetDistanceSquared(m_sQueueSample.m_vecPos); - if (distSquared < SOUND_INTENSITY) { - m_sQueueSample.m_fDistance = Sqrt(distSquared); - m_sQueueSample.m_nVolume = ComputeVolume(50, m_sQueueSample.m_fSoundIntensity, m_sQueueSample.m_fDistance); - if (m_sQueueSample.m_nVolume) { - m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY; - m_sQueueSample.m_nSampleIndex = SFX_JUMBO_TAXI; - m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; - m_sQueueSample.m_nFrequency = 15591; - m_sQueueSample.m_nReleasingVolumeModificator = 5; - m_sQueueSample.m_nCounter = i; - m_sQueueSample.m_fSpeedMultiplier = 2.0f; - m_sQueueSample.m_nReleasingVolumeDivider = 8; - m_sQueueSample.m_bIs2D = false; - m_sQueueSample.m_nLoopCount = 0; - m_sQueueSample.m_bReleasingSoundFlag = false; - m_sQueueSample.m_nEmittingVolume = 50; - m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex); - m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex); - m_sQueueSample.m_bReverbFlag = true; - m_sQueueSample.m_bRequireReflection = false; - AddSampleToRequestedQueue(); - } - } - } - } -} - -void -cAudioManager::ProcessWeather(int32 id) -{ - uint8 vol; - static uint8 counter = 0; - - if (m_asAudioEntities[id].m_AudioEvents && m_asAudioEntities[id].m_awAudioEvent[0] == SOUND_LIGHTNING) { - if (m_asAudioEntities[id].m_afVolume[0] >= 10.f) { - m_sQueueSample.m_nSampleIndex = SFX_EXPLOSION_1; - m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; - m_sQueueSample.m_nFrequency = RandomDisplacement(500) + 4000; - vol = (m_asAudioEntities[id].m_afVolume[0] - 10.f) + 40; - } else { - m_sQueueSample.m_nSampleIndex = SFX_EXPLOSION_2; - m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; - m_sQueueSample.m_nFrequency = RandomDisplacement(500) + 4000; - vol = (m_asAudioEntities[id].m_afVolume[0]) + 35; - } - m_sQueueSample.m_nVolume = vol; - if (TheCamera.SoundDistUp < 20.f) - m_sQueueSample.m_nVolume /= 2; - if (counter == 4) - counter = 0; - m_sQueueSample.m_nCounter = counter++; - m_sQueueSample.m_nReleasingVolumeModificator = 0; - m_sQueueSample.m_nOffset = (m_anRandomTable[2] & 15) + 55; - m_sQueueSample.m_bIs2D = true; - m_sQueueSample.m_nLoopCount = 1; - m_sQueueSample.m_bReleasingSoundFlag = true; - m_sQueueSample.m_nEmittingVolume = m_sQueueSample.m_nVolume; - m_sQueueSample.m_nLoopStart = 0; - m_sQueueSample.m_nLoopEnd = -1; - m_sQueueSample.m_bReverbFlag = false; - m_sQueueSample.m_bRequireReflection = false; - AddSampleToRequestedQueue(); - } - if (CWeather::Rain > 0.0f && (!CCullZones::CamNoRain() || !CCullZones::PlayerNoRain())) { - m_sQueueSample.m_nSampleIndex = SFX_RAIN; - m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_RAIN); - m_sQueueSample.m_nVolume = (int32)(25.f * CWeather::Rain); - m_sQueueSample.m_nCounter = 4; - m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; - m_sQueueSample.m_nReleasingVolumeModificator = 0; - m_sQueueSample.m_nOffset = 63; - m_sQueueSample.m_bIs2D = true; - m_sQueueSample.m_nLoopCount = 0; - m_sQueueSample.m_bReleasingSoundFlag = false; - m_sQueueSample.m_nReleasingVolumeDivider = 30; - m_sQueueSample.m_bReverbFlag = false; - m_sQueueSample.m_nEmittingVolume = m_sQueueSample.m_nVolume; - m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex); - m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex); - m_sQueueSample.m_bRequireReflection = false; - AddSampleToRequestedQueue(); - } -} - -bool -cAudioManager::ProcessWetRoadNoise(cVehicleParams *params) -{ - const float SOUND_INTENSITY = 30.0f; - - float relativeVelocity; - int32 emittingVol; - float modificator; - int freq; - float velChange; - - if (params->m_fDistance >= SQR(SOUND_INTENSITY)) - return false; - if (params->m_pTransmission) { - if (params->m_pVehicle->m_vecMoveSpeed.z) { - velChange = Abs(params->m_fVelocityChange); - if (velChange > 0.f) { - CalculateDistance(params->m_bDistanceCalculated, params->m_fDistance); - relativeVelocity = Min(1.0f, velChange / (0.5f * params->m_pTransmission->fMaxVelocity)); - emittingVol = 23.0f * relativeVelocity * CWeather::WetRoads; - m_sQueueSample.m_nVolume = ComputeVolume(emittingVol, SOUND_INTENSITY, m_sQueueSample.m_fDistance); - if (m_sQueueSample.m_nVolume) { - m_sQueueSample.m_nCounter = 1; - m_sQueueSample.m_nSampleIndex = SFX_ROAD_NOISE; - m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; - m_sQueueSample.m_bIs2D = false; - m_sQueueSample.m_nReleasingVolumeModificator = 3; - modificator = m_sQueueSample.m_fDistance / 6.f; - freq = SampleManager.GetSampleBaseFrequency(SFX_ROAD_NOISE); - m_sQueueSample.m_nFrequency = freq + freq * modificator; - m_sQueueSample.m_nLoopCount = 0; - m_sQueueSample.m_nEmittingVolume = emittingVol; - m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex); - m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex); - m_sQueueSample.m_fSpeedMultiplier = 6.0f; - m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY; - m_sQueueSample.m_bReleasingSoundFlag = false; - m_sQueueSample.m_nReleasingVolumeDivider = 4; - m_sQueueSample.m_bReverbFlag = true; - m_sQueueSample.m_bRequireReflection = false; - AddSampleToRequestedQueue(); - } - } - } - } - return true; -} - -void -cAudioManager::ProcessWorkShopScriptObject(uint8 sound) -{ - float distSquared; - - switch (sound) { - case SCRIPT_SOUND_WORK_SHOP_LOOP_S: - case SCRIPT_SOUND_WORK_SHOP_LOOP_L: - m_sQueueSample.m_fSoundIntensity = 20.0f; - break; - default: - return; - } - distSquared = GetDistanceSquared(m_sQueueSample.m_vecPos); - if (distSquared < SQR(m_sQueueSample.m_fSoundIntensity)) { - m_sQueueSample.m_fDistance = Sqrt(distSquared); - m_sQueueSample.m_nVolume = ComputeVolume(30, m_sQueueSample.m_fSoundIntensity, m_sQueueSample.m_fDistance); - if (m_sQueueSample.m_nVolume) { - m_sQueueSample.m_nSampleIndex = SFX_WORKSHOP_1; - m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; - m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_WORKSHOP_1); - m_sQueueSample.m_nCounter = 0; - m_sQueueSample.m_bIs2D = false; - m_sQueueSample.m_nLoopCount = 0; - m_sQueueSample.m_bReleasingSoundFlag = false; - m_sQueueSample.m_nReleasingVolumeModificator = 5; - m_sQueueSample.m_fSpeedMultiplier = 2.0f; - m_sQueueSample.m_nEmittingVolume = 30; - m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex); - m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex); - m_sQueueSample.m_bReverbFlag = true; - m_sQueueSample.m_bRequireReflection = false; - AddSampleToRequestedQueue(); - } - } -} - -int32 -cAudioManager::RandomDisplacement(uint32 seed) const -{ - int32 value; - - static bool bIsEven = true; - static uint32 base = 0; - - if (!seed) - return 0; - - value = m_anRandomTable[(base + seed) % 5] % seed; - base += value; - - if (value % 2) { - bIsEven = !bIsEven; - } - if (!bIsEven) - value = -value; - return value; -} - -void -cAudioManager::ReacquireDigitalHandle() const -{ - if (m_bIsInitialised) { - SampleManager.ReacquireDigitalHandle(); - } -} - -void -cAudioManager::ReleaseDigitalHandle() const -{ - if (m_bIsInitialised) { - SampleManager.ReleaseDigitalHandle(); - } -} - -void -cAudioManager::ResetAudioLogicTimers(uint32 timer) -{ - gPornNextTime = timer; - gNextCryTime = timer; - gSawMillNextTime = timer; - gCellNextTime = timer; - gShopNextTime = timer; - gHomeNextTime = timer; - gAirportNextTime = timer; - gDocksNextTime = timer; - gCinemaNextTime = timer; - for (int32 i = 0; i < m_nAudioEntitiesTotal; i++) { - if (m_asAudioEntities[m_anAudioEntityIndices[i]].m_nType == AUDIOTYPE_PHYSICAL) { - CPed *ped = (CPed *)m_asAudioEntities[m_anAudioEntityIndices[i]].m_pEntity; - if (ped->IsPed()) { - ped->m_lastSoundStart = timer; - ped->m_soundStart = timer + m_anRandomTable[0] % 3000; - } - } - } - ClearMissionAudio(); - SampleManager.StopChannel(policeChannel); -} - -void -cAudioManager::ResetTimers(uint32 time) -{ - if (m_bIsInitialised) { - m_bTimerJustReset = true; - m_nTimer = time; - ClearRequestedQueue(); - if (m_nActiveSampleQueue) { - m_nActiveSampleQueue = 0; - ClearRequestedQueue(); - m_nActiveSampleQueue = 1; - } else { - m_nActiveSampleQueue = 1; - ClearRequestedQueue(); - m_nActiveSampleQueue = 0; - } - ClearActiveSamples(); - ClearMissionAudio(); - SampleManager.StopChannel(policeChannel); - SampleManager.SetEffectsFadeVolume(0); - SampleManager.SetMusicFadeVolume(0); - MusicManager.ResetMusicAfterReload(); -#ifdef AUDIO_OAL - SampleManager.Service(); -#endif - } -} - -void -cAudioManager::Service() -{ - GenerateIntegerRandomNumberTable(); - if (m_bTimerJustReset) { - ResetAudioLogicTimers(m_nTimer); - MusicManager.ResetTimers(m_nTimer); - m_bTimerJustReset = false; - } - if (m_bIsInitialised) { - m_nPreviousUserPause = m_nUserPause; - m_nUserPause = CTimer::GetIsUserPaused(); - UpdateReflections(); - ServiceSoundEffects(); - MusicManager.Service(); - } -} - -void -cAudioManager::ServiceSoundEffects() -{ - m_bFifthFrameFlag = (m_FrameCounter++ % 5) == 0; - if (m_nUserPause && !m_nPreviousUserPause) { - for (int32 i = 0; i < allChannels; i++) - SampleManager.StopChannel(i); - - ClearRequestedQueue(); - if (m_nActiveSampleQueue) { - m_nActiveSampleQueue = 0; - ClearRequestedQueue(); - m_nActiveSampleQueue = 1; - } else { - m_nActiveSampleQueue = 1; - ClearRequestedQueue(); - m_nActiveSampleQueue = 0; - } - ClearActiveSamples(); - } - m_nActiveSampleQueue = m_nActiveSampleQueue != 1; - ProcessReverb(); - ProcessSpecial(); - ClearRequestedQueue(); - InterrogateAudioEntities(); - m_sPedComments.Process(); - ServicePoliceRadio(); - ServiceCollisions(); - AddReleasingSounds(); - ProcessMissionAudio(); - AdjustSamplesVolume(); - ProcessActiveQueues(); -#ifdef AUDIO_OAL - SampleManager.Service(); -#endif - for (int32 i = 0; i < m_sAudioScriptObjectManager.m_nScriptObjectEntityTotal; ++i) { - cAudioScriptObject *object = (cAudioScriptObject *)m_asAudioEntities[m_sAudioScriptObjectManager.m_anScriptObjectEntityIndices[i]].m_pEntity; - delete object; - m_asAudioEntities[m_sAudioScriptObjectManager.m_anScriptObjectEntityIndices[i]].m_pEntity = nil; - DestroyEntity(m_sAudioScriptObjectManager.m_anScriptObjectEntityIndices[i]); - } - m_sAudioScriptObjectManager.m_nScriptObjectEntityTotal = 0; -} - -int8 -cAudioManager::SetCurrent3DProvider(uint8 which) -{ - if (!m_bIsInitialised) - return -1; - for (uint8 i = 0; i < m_nActiveSamples + 1; ++i) - SampleManager.StopChannel(i); - ClearRequestedQueue(); - if (m_nActiveSampleQueue == 0) - m_nActiveSampleQueue = 1; - else - m_nActiveSampleQueue = 0; - ClearRequestedQueue(); - ClearActiveSamples(); - int8 current = SampleManager.SetCurrent3DProvider(which); - if (current > 0) { - m_nActiveSamples = SampleManager.GetMaximumSupportedChannels(); - if (m_nActiveSamples > 1) - --m_nActiveSamples; - } - return current; -} - -void -cAudioManager::SetDynamicAcousticModelingStatus(bool status) -{ - m_bDynamicAcousticModelingStatus = status; -} - -void -cAudioManager::SetEffectsFadeVolume(uint8 volume) const -{ - SampleManager.SetEffectsFadeVolume(volume); -} - -void -cAudioManager::SetEffectsMasterVolume(uint8 volume) const -{ - SampleManager.SetEffectsMasterVolume(volume); -} - -void -cAudioManager::SetEntityStatus(int32 id, uint8 status) -{ - if (m_bIsInitialised && id >= 0 && id < totalAudioEntitiesSlots && m_asAudioEntities[id].m_bIsUsed) - m_asAudioEntities[id].m_nStatus = status; -} - -void -cAudioManager::SetMissionAudioLocation(float x, float y, float z) -{ - if (m_bIsInitialised) { - m_sMissionAudio.m_bPredefinedProperties = false; - m_sMissionAudio.m_vecPos = CVector(x, y, z); - } -} - -void -cAudioManager::SetMusicFadeVolume(uint8 volume) const -{ - SampleManager.SetMusicFadeVolume(volume); -} - -void -cAudioManager::SetMusicMasterVolume(uint8 volume) const -{ - SampleManager.SetMusicMasterVolume(volume); -} - -void -cAudioManager::SetSpeakerConfig(int32 conf) const -{ - SampleManager.SetSpeakerConfig(conf); -} - -bool -cAudioManager::SetupJumboEngineSound(uint8 vol, int32 freq) -{ - const float SOUND_INTENSITY = 180.0f; - if (m_sQueueSample.m_fDistance >= SOUND_INTENSITY) - return false; - - uint8 emittingVol = vol - gJumboVolOffsetPercentage / 100; - m_sQueueSample.m_nVolume = ComputeVolume(emittingVol, SOUND_INTENSITY, m_sQueueSample.m_fDistance); - if (m_sQueueSample.m_nVolume != 0) { - m_sQueueSample.m_nCounter = 3; - m_sQueueSample.m_nSampleIndex = SFX_JUMBO_ENGINE; - m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; - m_sQueueSample.m_bIs2D = false; - m_sQueueSample.m_nReleasingVolumeModificator = 1; - m_sQueueSample.m_nFrequency = freq; - m_sQueueSample.m_nLoopCount = 0; - m_sQueueSample.m_nEmittingVolume = emittingVol; - m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex); - m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex); - m_sQueueSample.m_fSpeedMultiplier = 4.0f; - m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY; - m_sQueueSample.m_bReleasingSoundFlag = false; - m_sQueueSample.m_nReleasingVolumeDivider = 4; - m_sQueueSample.m_bReverbFlag = true; - m_sQueueSample.m_bRequireReflection = false; - AddSampleToRequestedQueue(); - } - return true; -} - -bool -cAudioManager::SetupJumboFlySound(uint8 emittingVol) -{ - const float SOUND_INTENSITY = 440.0f; - if (m_sQueueSample.m_fDistance >= SOUND_INTENSITY) - return false; - - int32 vol = ComputeVolume(emittingVol, SOUND_INTENSITY, m_sQueueSample.m_fDistance); - m_sQueueSample.m_nVolume = vol; - if (m_sQueueSample.m_nVolume != 0) { - m_sQueueSample.m_nSampleIndex = SFX_JUMBO_DIST_FLY; - m_sQueueSample.m_nCounter = 0; - m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; - m_sQueueSample.m_bIs2D = false; - m_sQueueSample.m_nReleasingVolumeModificator = 1; - m_sQueueSample.m_nEmittingVolume = emittingVol; - m_sQueueSample.m_nLoopCount = 0; - m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_JUMBO_DIST_FLY); - m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex); - m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY; - m_sQueueSample.m_bReleasingSoundFlag = false; - m_sQueueSample.m_fSpeedMultiplier = 4.0f; - m_sQueueSample.m_bReverbFlag = true; - m_sQueueSample.m_nReleasingVolumeDivider = 5; - m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex); - AddSampleToRequestedQueue(); - } - return true; -} - -bool -cAudioManager::SetupJumboRumbleSound(uint8 emittingVol) -{ - const float SOUND_INTENSITY = 240.0f; - if (m_sQueueSample.m_fDistance >= SOUND_INTENSITY) - return false; - - m_sQueueSample.m_nVolume = ComputeVolume(emittingVol, SOUND_INTENSITY, m_sQueueSample.m_fDistance); - - if (m_sQueueSample.m_nVolume != 0) { - m_sQueueSample.m_nCounter = 5; - m_sQueueSample.m_nSampleIndex = SFX_JUMBO_RUMBLE; - m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; - m_sQueueSample.m_bIs2D = true; - m_sQueueSample.m_nReleasingVolumeModificator = 1; - m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_JUMBO_RUMBLE); - m_sQueueSample.m_nLoopCount = 0; - m_sQueueSample.m_nEmittingVolume = emittingVol; - m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex); - m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex); - m_sQueueSample.m_fSpeedMultiplier = 4.0f; - m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY; - m_sQueueSample.m_bReleasingSoundFlag = false; - m_sQueueSample.m_nReleasingVolumeDivider = 12; - m_sQueueSample.m_nOffset = 0; - m_sQueueSample.m_bReverbFlag = true; - m_sQueueSample.m_bRequireReflection = false; - AddSampleToRequestedQueue(); - m_sQueueSample.m_nCounter = 6; - m_sQueueSample.m_nSampleIndex = SFX_JUMBO_RUMBLE; - m_sQueueSample.m_nFrequency += 200; - m_sQueueSample.m_nOffset = maxVolume; - AddSampleToRequestedQueue(); - } - return true; -} - -bool -cAudioManager::SetupJumboTaxiSound(uint8 vol) -{ - const float SOUND_INTENSITY = 180.0f; - if (m_sQueueSample.m_fDistance >= SOUND_INTENSITY) - return false; - - uint8 emittingVol = (vol / 2) + ((vol / 2) * m_sQueueSample.m_fDistance / SOUND_INTENSITY); - - if (m_sQueueSample.m_fDistance / SOUND_INTENSITY < 0.7f) - emittingVol -= emittingVol * gJumboVolOffsetPercentage / 100; - m_sQueueSample.m_nVolume = ComputeVolume(emittingVol, SOUND_INTENSITY, m_sQueueSample.m_fDistance); - - if (m_sQueueSample.m_nVolume != 0) { - m_sQueueSample.m_nCounter = 1; - m_sQueueSample.m_nSampleIndex = SFX_JUMBO_TAXI; - m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; - m_sQueueSample.m_bIs2D = false; - m_sQueueSample.m_nReleasingVolumeModificator = 1; - m_sQueueSample.m_nFrequency = GetJumboTaxiFreq(); - m_sQueueSample.m_nLoopCount = 0; - m_sQueueSample.m_nEmittingVolume = emittingVol; - m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex); - m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex); - m_sQueueSample.m_fSpeedMultiplier = 4.0f; - m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY; - m_sQueueSample.m_bReleasingSoundFlag = false; - m_sQueueSample.m_nReleasingVolumeDivider = 4; - m_sQueueSample.m_bReverbFlag = true; - m_sQueueSample.m_bRequireReflection = false; - AddSampleToRequestedQueue(); - } - return true; -} - -bool -cAudioManager::SetupJumboWhineSound(uint8 emittingVol, int32 freq) -{ - const float SOUND_INTENSITY = 170.0f; - - if (m_sQueueSample.m_fDistance >= SOUND_INTENSITY) - return false; - - m_sQueueSample.m_nVolume = ComputeVolume(emittingVol, SOUND_INTENSITY, m_sQueueSample.m_fDistance); - - if (m_sQueueSample.m_nVolume != 0) { - m_sQueueSample.m_nCounter = 2; - m_sQueueSample.m_nSampleIndex = SFX_JUMBO_WHINE; - m_sQueueSample.m_nBankIndex = SAMPLEBANK_MAIN; - m_sQueueSample.m_bIs2D = false; - m_sQueueSample.m_nReleasingVolumeModificator = 1; - m_sQueueSample.m_nFrequency = freq; - m_sQueueSample.m_nLoopCount = 0; - m_sQueueSample.m_nEmittingVolume = emittingVol; - m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex); - m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex); - m_sQueueSample.m_fSpeedMultiplier = 4.0f; - m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY; - m_sQueueSample.m_bReleasingSoundFlag = false; - m_sQueueSample.m_nReleasingVolumeDivider = 4; - m_sQueueSample.m_bReverbFlag = true; - m_sQueueSample.m_bRequireReflection = false; - AddSampleToRequestedQueue(); - } - return true; -} - void -cAudioManager::SetupPedComments(cPedParams *params, uint32 sound) +cAudioManager::ClearRequestedQueue() { - CPed *ped = params->m_pPed; - uint8 emittingVol; - float soundIntensity; - tPedComment pedComment; - - if (ped != nil) { - switch (sound) { - case SOUND_AMMUNATION_WELCOME_1: - pedComment.m_nSampleIndex = SFX_AMMU_D; - break; - case SOUND_AMMUNATION_WELCOME_2: - pedComment.m_nSampleIndex = SFX_AMMU_E; - break; - case SOUND_AMMUNATION_WELCOME_3: - pedComment.m_nSampleIndex = SFX_AMMU_F; - break; - default: - pedComment.m_nSampleIndex = GetPedCommentSfx(ped, sound); - if (pedComment.m_nSampleIndex == NO_SAMPLE) - return; - break; - } - - soundIntensity = 50.0f; - } else { - switch (sound) { - case SOUND_PED_HELI_PLAYER_FOUND: - soundIntensity = 400.0f; - pedComment.m_nSampleIndex = GetRandomNumberInRange(m_sQueueSample.m_nEntityIndex % 4, SFX_POLICE_HELI_1, SFX_POLICE_HELI_29); - break; - case SOUND_PED_BODYCAST_HIT: - if (CTimer::GetTimeInMilliseconds() <= gNextCryTime) - return; - soundIntensity = 50.0f; - gNextCryTime = CTimer::GetTimeInMilliseconds() + 500; - pedComment.m_nSampleIndex = GetRandomNumberInRange(m_sQueueSample.m_nEntityIndex % 4, SFX_PLASTER_BLOKE_1, SFX_PLASTER_BLOKE_4); - break; - case SOUND_INJURED_PED_MALE_OUCH: - case SOUND_INJURED_PED_MALE_PRISON: - soundIntensity = 50.0f; - pedComment.m_nSampleIndex = GetRandomNumberInRange(m_sQueueSample.m_nEntityIndex % 4, SFX_GENERIC_MALE_GRUNT_1, SFX_GENERIC_MALE_GRUNT_15); - break; - case SOUND_INJURED_PED_FEMALE: - soundIntensity = 50.0f; - pedComment.m_nSampleIndex = GetRandomNumberInRange(m_sQueueSample.m_nEntityIndex % 4, SFX_GENERIC_FEMALE_GRUNT_1, SFX_GENERIC_FEMALE_GRUNT_11); - break; - default: - return; - } - } - - if (params->m_fDistance < SQR(soundIntensity)) { - CalculateDistance(params->m_bDistanceCalculated, params->m_fDistance); - if (sound != SOUND_PAGER) { - switch (sound) { - case SOUND_AMMUNATION_WELCOME_1: - case SOUND_AMMUNATION_WELCOME_2: - case SOUND_AMMUNATION_WELCOME_3: - emittingVol = maxVolume; - break; - default: - if (CWorld::GetIsLineOfSightClear(TheCamera.GetPosition(), m_sQueueSample.m_vecPos, true, false, false, false, false, false)) - emittingVol = maxVolume; - else - emittingVol = 31; - break; - } - m_sQueueSample.m_nVolume = ComputeVolume(emittingVol, soundIntensity, m_sQueueSample.m_fDistance); - pedComment.m_nProcess = 10; - if (m_sQueueSample.m_nVolume != 0) { - pedComment.m_nEntityIndex = m_sQueueSample.m_nEntityIndex; - pedComment.m_vecPos = m_sQueueSample.m_vecPos; - pedComment.m_fDistance = m_sQueueSample.m_fDistance; - pedComment.m_bVolume = m_sQueueSample.m_nVolume; - m_sPedComments.Add(&pedComment); - } - } - } -} - -void -cAudioManager::Terminate() -{ - if (m_bIsInitialised) { - MusicManager.Terminate(); - - for (uint32 i = 0; i < totalAudioEntitiesSlots; i++) { - m_asAudioEntities[i].m_bIsUsed = false; - m_anAudioEntityIndices[i] = ARRAY_SIZE(m_anAudioEntityIndices); - } - - m_nAudioEntitiesTotal = 0; - m_sAudioScriptObjectManager.m_nScriptObjectEntityTotal = 0; - PreTerminateGameSpecificShutdown(); - - for (uint32 i = 0; i < MAX_SAMPLEBANKS; i++) { - if (SampleManager.IsSampleBankLoaded(i)) - SampleManager.UnloadSampleBank(i); - } - - SampleManager.Terminate(); - - m_bIsInitialised = false; - PostTerminateGameSpecificShutdown(); + for (int32 i = 0; i < m_nActiveSamples; i++) { + m_abSampleQueueIndexTable[m_nActiveSampleQueue][i] = m_nActiveSamples; } + m_SampleRequestQueuesStatus[m_nActiveSampleQueue] = 0; } void -cAudioManager::TranslateEntity(Const CVector *in, CVector *out) const -{ - *out = MultiplyInverse(TheCamera.GetMatrix(), *in); -} - -void -cAudioManager::UpdateGasPedalAudio(CAutomobile *automobile) +cAudioManager::ClearActiveSamples() { - float newGasPedalAudio; - - float gasPedal = Abs(automobile->m_fGasPedal); - float gasPedalAudio = automobile->m_fGasPedalAudio; - - if (gasPedalAudio < gasPedal) { - newGasPedalAudio = gasPedalAudio + 0.09f; - if (gasPedal <= newGasPedalAudio) - newGasPedalAudio = gasPedal; - } else { - newGasPedalAudio = gasPedalAudio - 0.07f; - if (gasPedal >= newGasPedalAudio) - newGasPedalAudio = gasPedal; + for (int32 i = 0; i < m_nActiveSamples; i++) { + m_asActiveSamples[i].m_nEntityIndex = AEHANDLE_NONE; + m_asActiveSamples[i].m_nCounter = 0; + m_asActiveSamples[i].m_nSampleIndex = NO_SAMPLE; + m_asActiveSamples[i].m_nBankIndex = SAMPLEBANK_INVALID; + m_asActiveSamples[i].m_bIs2D = false; + m_asActiveSamples[i].m_nReleasingVolumeModificator = 5; + m_asActiveSamples[i].m_nFrequency = 0; + m_asActiveSamples[i].m_nVolume = 0; + m_asActiveSamples[i].m_nEmittingVolume = 0; + m_asActiveSamples[i].m_fDistance = 0.0f; + m_asActiveSamples[i].m_bIsProcessed = false; + m_asActiveSamples[i].m_bLoopEnded = false; + m_asActiveSamples[i].m_nLoopCount = 1; + m_asActiveSamples[i].m_nLoopStart = 0; + m_asActiveSamples[i].m_nLoopEnd = -1; + m_asActiveSamples[i].m_fSpeedMultiplier = 0.0f; + m_asActiveSamples[i].m_fSoundIntensity = 200.0f; + m_asActiveSamples[i].m_nOffset = 63; + m_asActiveSamples[i].m_bReleasingSoundFlag = false; + m_asActiveSamples[i].m_nCalculatedVolume = 0; + m_asActiveSamples[i].m_nReleasingVolumeDivider = 0; + m_asActiveSamples[i].m_nVolumeChange = -1; + m_asActiveSamples[i].m_vecPos = {0.0f, 0.0f, 0.0f}; + m_asActiveSamples[i].m_bReverbFlag = false; + m_asActiveSamples[i].m_nLoopsRemaining = 0; + m_asActiveSamples[i].m_bRequireReflection = false; } - automobile->m_fGasPedalAudio = newGasPedalAudio; } void -cAudioManager::UpdateReflections() -{ - const CVector &camPos = TheCamera.GetPosition(); - CColPoint colpoint; - CEntity *ent; - - if (m_FrameCounter % 8 == 0) { - m_avecReflectionsPos[0] = camPos; - m_avecReflectionsPos[0].y += 50.f; - if (CWorld::ProcessLineOfSight(camPos, m_avecReflectionsPos[0], colpoint, ent, true, false, false, true, false, true, true)) - m_afReflectionsDistances[0] = Distance(camPos, colpoint.point); - else - m_afReflectionsDistances[0] = 50.0f; - } else if ((m_FrameCounter + 1) % 8 == 0) { - m_avecReflectionsPos[1] = camPos; - m_avecReflectionsPos[1].y -= 50.0f; - if (CWorld::ProcessLineOfSight(camPos, m_avecReflectionsPos[1], colpoint, ent, true, false, false, true, false, true, true)) - m_afReflectionsDistances[1] = Distance(camPos, colpoint.point); - else - m_afReflectionsDistances[1] = 50.0f; - } else if ((m_FrameCounter + 2) % 8 == 0) { - m_avecReflectionsPos[2] = camPos; - m_avecReflectionsPos[2].x -= 50.0f; - if (CWorld::ProcessLineOfSight(camPos, m_avecReflectionsPos[2], colpoint, ent, true, false, false, true, false, true, true)) - m_afReflectionsDistances[2] = Distance(camPos, colpoint.point); - else - m_afReflectionsDistances[2] = 50.0f; - } else if ((m_FrameCounter + 3) % 8 == 0) { - m_avecReflectionsPos[3] = camPos; - m_avecReflectionsPos[3].x += 50.0f; - if (CWorld::ProcessLineOfSight(camPos, m_avecReflectionsPos[3], colpoint, ent, true, false, false, true, false, true, true)) - m_afReflectionsDistances[3] = Distance(camPos, colpoint.point); - else - m_afReflectionsDistances[3] = 50.0f; - } else if ((m_FrameCounter + 4) % 8 == 0) { - m_avecReflectionsPos[4] = camPos; - m_avecReflectionsPos[4].z += 50.0f; - if (CWorld::ProcessVerticalLine(camPos, m_avecReflectionsPos[4].z, colpoint, ent, true, false, false, false, true, false, nil)) - m_afReflectionsDistances[4] = colpoint.point.z - camPos.z; - else - m_afReflectionsDistances[4] = 50.0f; - } -} - -bool -cAudioManager::UsesReverseWarning(int32 model) const -{ - return model == LINERUN || model == FIRETRUK || model == TRASH || model == BUS || model == COACH; -} - -bool -cAudioManager::UsesSiren(int32 model) const -{ - switch (model) { - case FIRETRUK: - case AMBULAN: - case FBICAR: - case POLICE: - case ENFORCER: - case PREDATOR: - return true; - default: - return false; - } -} - -bool -cAudioManager::UsesSirenSwitching(int32 model) const +cAudioManager::GenerateIntegerRandomNumberTable() { - switch (model) { - case AMBULAN: - case POLICE: - case ENFORCER: - case PREDATOR: - return true; - default: - return false; + for (int32 i = 0; i < ARRAY_SIZE(m_anRandomTable); i++) { + m_anRandomTable[i] = myrand(); } } +#ifdef GTA_PC void cAudioManager::AdjustSamplesVolume() { @@ -9881,3 +966,4 @@ cAudioManager::ComputeEmittingVolume(uint8 emittingVolume, float intensity, floa return (quatIntensity - (dist - diffIntensity)) * (float)emittingVolume / quatIntensity; return emittingVolume; } +#endif diff --git a/src/audio/AudioManager.h b/src/audio/AudioManager.h index 99d67444..f53034fe 100644 --- a/src/audio/AudioManager.h +++ b/src/audio/AudioManager.h @@ -75,7 +75,18 @@ public: uint8 m_nCommentsInBank[NUM_PED_COMMENTS_BANKS]; uint8 m_nActiveBank; - cPedComments(); + cPedComments() + { + for (int i = 0; i < NUM_PED_COMMENTS_SLOTS; i++) + for (int j = 0; j < NUM_PED_COMMENTS_BANKS; j++) { + m_asPedComments[j][i].m_nProcess = -1; + m_nIndexMap[j][i] = NUM_PED_COMMENTS_SLOTS; + } + + for (int i = 0; i < NUM_PED_COMMENTS_BANKS; i++) + m_nCommentsInBank[i] = 0; + m_nActiveBank = 0; + } void Add(tPedComment *com); void Process(); }; @@ -222,91 +233,15 @@ public: float speedMultiplier) const; int32 ComputePan(float, CVector *); uint8 ComputeVolume(uint8 emittingVolume, float soundIntensity, float distance) const; - int32 CreateEntity(int32 type, void *entity); + int32 CreateEntity(eAudioType type, void *entity); void DestroyAllGameCreatedEntities(); void DestroyEntity(int32 id); - void DoJumboVolOffset() const; void DoPoliceRadioCrackle(); // functions returning talk sfx, // order from GetPedCommentSfx - uint32 GetPlayerTalkSfx(int16 sound); - uint32 GetCopTalkSfx(int16 sound); - uint32 GetSwatTalkSfx(int16 sound); - uint32 GetFBITalkSfx(int16 sound); - uint32 GetArmyTalkSfx(int16 sound); - uint32 GetMedicTalkSfx(int16 sound); - uint32 GetFiremanTalkSfx(int16 sound); - uint32 GetNormalMaleTalkSfx(int16 sound); - uint32 GetTaxiDriverTalkSfx(int16 sound); - uint32 GetPimpTalkSfx(int16 sound); - uint32 GetMafiaTalkSfx(int16 sound); - uint32 GetTriadTalkSfx(int16 sound); - uint32 GetDiabloTalkSfx(int16 sound); - uint32 GetYakuzaTalkSfx(int16 sound); - uint32 GetYardieTalkSfx(int16 sound); - uint32 GetColumbianTalkSfx(int16 sound); - uint32 GetHoodTalkSfx(int16 sound); - uint32 GetBlackCriminalTalkSfx(int16 sound); - uint32 GetWhiteCriminalTalkSfx(int16 sound); - uint32 GetMaleNo2TalkSfx(int16 sound); - uint32 GetBlackProjectMaleTalkSfx(int16 sound, int32 model); - uint32 GetWhiteFatMaleTalkSfx(int16 sound); - uint32 GetBlackFatMaleTalkSfx(int16 sound); - uint32 GetBlackCasualFemaleTalkSfx(int16 sound); - uint32 GetWhiteCasualFemaleTalkSfx(int16 sound); - uint32 GetFemaleNo3TalkSfx(int16 sound); - uint32 GetBlackFatFemaleTalkSfx(int16 sound); - uint32 GetWhiteFatFemaleTalkSfx(int16 sound); - uint32 GetBlackFemaleProstituteTalkSfx(int16 sound); - uint32 GetWhiteFemaleProstituteTalkSfx(int16 sound); - uint32 GetBlackProjectFemaleOldTalkSfx(int16 sound); - uint32 GetBlackProjectFemaleYoungTalkSfx(int16 sound); - uint32 GetChinatownMaleOldTalkSfx(int16 sound); - uint32 GetChinatownMaleYoungTalkSfx(int16 sound); - uint32 GetChinatownFemaleOldTalkSfx(int16 sound); - uint32 GetChinatownFemaleYoungTalkSfx(int16 sound); - uint32 GetLittleItalyMaleTalkSfx(int16 sound); - uint32 GetLittleItalyFemaleOldTalkSfx(int16 sound); - uint32 GetLittleItalyFemaleYoungTalkSfx(int16 sound); - uint32 GetWhiteDockerMaleTalkSfx(int16 sound); - uint32 GetBlackDockerMaleTalkSfx(int16 sound); - uint32 GetScumMaleTalkSfx(int16 sound); - uint32 GetScumFemaleTalkSfx(int16 sound); - uint32 GetWhiteWorkerMaleTalkSfx(int16 sound); - uint32 GetBlackWorkerMaleTalkSfx(int16 sound); - uint32 GetBusinessMaleYoungTalkSfx(int16 sound, int32 model); - uint32 GetBusinessMaleOldTalkSfx(int16 sound); - uint32 GetWhiteBusinessFemaleTalkSfx(int16 sound, int32 model); - uint32 GetBlackBusinessFemaleTalkSfx(int16 sound); - uint32 GetSupermodelMaleTalkSfx(int16 sound); - uint32 GetSupermodelFemaleTalkSfx(int16 sound); - uint32 GetStewardMaleTalkSfx(int16 sound); - uint32 GetStewardFemaleTalkSfx(int16 sound); - uint32 GetFanMaleTalkSfx(int16 sound, int32 model); - uint32 GetFanFemaleTalkSfx(int16 sound); - uint32 GetHospitalMaleTalkSfx(int16 sound); - uint32 GetHospitalFemaleTalkSfx(int16 sound); - uint32 GetWhiteConstructionWorkerTalkSfx(int16 sound); - uint32 GetBlackConstructionWorkerTalkSfx(int16 sound); - uint32 GetShopperFemaleTalkSfx(int16 sound, int32 model); - uint32 GetStudentMaleTalkSfx(int16 sound); - uint32 GetStudentFemaleTalkSfx(int16 sound); - uint32 GetCasualMaleOldTalkSfx(int16 sound); - - uint32 GetSpecialCharacterTalkSfx(int32 modelIndex, int32 sound); - uint32 GetEightTalkSfx(int16 sound); - uint32 GetFrankieTalkSfx(int16 sound); - uint32 GetMistyTalkSfx(int16 sound); - uint32 GetOJGTalkSfx(int16 sound); - uint32 GetCatatalinaTalkSfx(int16 sound); - uint32 GetBomberTalkSfx(int16 sound); - uint32 GetSecurityGuardTalkSfx(int16 sound); - uint32 GetChunkyTalkSfx(int16 sound); - - uint32 GetGenericMaleTalkSfx(int16 sound); - uint32 GetGenericFemaleTalkSfx(int16 sound); + // TODO: miami // end of functions returning talk sfx void GenerateIntegerRandomNumberTable(); @@ -318,7 +253,7 @@ public: float GetCollisionRatio(float a, float b, float c, float d) const; float GetDistanceSquared(const CVector &v) const; int32 GetJumboTaxiFreq() const; - bool GetMissionAudioLoadingStatus() const; + uint8 GetMissionAudioLoadingStatus() const; int8 GetMissionScriptPoliceAudioPlayingStatus() const; uint8 GetNum3DProvidersAvailable() const; int32 GetPedCommentSfx(CPed *ped, int32 sound); @@ -387,7 +322,6 @@ public: void ProcessModelCarEngine(cVehicleParams *params); void ProcessOneShotScriptObject(uint8 sound); void ProcessPed(CPhysical *ped); - void ProcessPedHeadphones(cPedParams *params); void ProcessPedOneShots(cPedParams *params); void ProcessPhysical(int32 id); void ProcessPlane(cVehicleParams *params); @@ -434,14 +368,14 @@ public: void ServiceSoundEffects(); int8 SetCurrent3DProvider(uint8 which); void SetDynamicAcousticModelingStatus(bool status); - void SetEffectsFadeVolume(uint8 volume) const; + void SetEffectsFadeVol(uint8 volume) const; void SetEffectsMasterVolume(uint8 volume) const; void SetEntityStatus(int32 id, uint8 status); uint32 SetLoopingCollisionRequestedSfxFreqAndGetVol(const cAudioCollision &audioCollision); void SetMissionAudioLocation(float x, float y, float z); void SetMissionScriptPoliceAudio(int32 sfx) const; void SetMonoMode(uint8); // todo (mobile) - void SetMusicFadeVolume(uint8 volume) const; + void SetMusicFadeVol(uint8 volume) const; void SetMusicMasterVolume(uint8 volume) const; void SetSpeakerConfig(int32 conf) const; void SetUpLoopingCollisionSound(const cAudioCollision &col, uint8 counter); @@ -464,11 +398,11 @@ public: bool UsesSiren(int32 model) const; bool UsesSirenSwitching(int32 model) const; +#ifdef GTA_PC // only used in pc void AdjustSamplesVolume(); uint8 ComputeEmittingVolume(uint8 emittingVolume, float intensity, float dist); - - void DebugShit(); +#endif }; #ifdef AUDIO_MSS diff --git a/src/audio/AudioScriptObject.cpp b/src/audio/AudioScriptObject.cpp index 3d84006d..69d80fbc 100644 --- a/src/audio/AudioScriptObject.cpp +++ b/src/audio/AudioScriptObject.cpp @@ -7,7 +7,7 @@ void cAudioScriptObject::Reset() { - AudioId = SCRSOUND_INVALID; + AudioId = SCRIPT_SOUND_INVALID; Posn = CVector(0.0f, 0.0f, 0.0f); AudioEntity = AEHANDLE_NONE; } diff --git a/src/audio/AudioScriptObject.h b/src/audio/AudioScriptObject.h index ecc07fdf..ff36474d 100644 --- a/src/audio/AudioScriptObject.h +++ b/src/audio/AudioScriptObject.h @@ -1,135 +1,5 @@ #pragma once -enum -{ - SCRSOUND_TEST_1, - _SCRSOUND_UNK_1, - _SCRSOUND_UNK_2, - _SCRSOUND_UNK_3, - _SCRSOUND_CLUB_1_S, - _SCRSOUND_CLUB_1_L, - _SCRSOUND_CLUB_2_S, - _SCRSOUND_CLUB_2_L, - _SCRSOUND_CLUB_3_S, - _SCRSOUND_CLUB_3_L, - _SCRSOUND_CLUB_4_S, - _SCRSOUND_CLUB_4_L, - _SCRSOUND_CLUB_5_S, - _SCRSOUND_CLUB_5_L, - _SCRSOUND_CLUB_6_S, - _SCRSOUND_CLUB_6_L, - _SCRSOUND_CLUB_7_S, - _SCRSOUND_CLUB_7_L, - _SCRSOUND_CLUB_8_S, - _SCRSOUND_CLUB_8_L, - _SCRSOUND_CLUB_9_S, - _SCRSOUND_CLUB_9_L, - _SCRSOUND_CLUB_10_S, - _SCRSOUND_CLUB_10_L, - _SCRSOUND_CLUB_11_S, - _SCRSOUND_CLUB_11_L, - _SCRSOUND_CLUB_12_S, - _SCRSOUND_CLUB_12_L, - _SCRSOUND_CLUB_RAGGA_S, - _SCRSOUND_CLUB_RAGGA_L, - SCRSOUND_STRIP_CLUB_LOOP_1_S, - _SCRSOUND_STRIP_CLUB_LOOP_1_L, - SCRSOUND_STRIP_CLUB_LOOP_2_S, - _SCRSOUND_STRIP_CLUB_LOOP_2_L, - _SCRSOUND_SFX_WORKSHOP_1, - _SCRSOUND_SFX_WORKSHOP_2, - _SCRSOUND_SAWMILL_LOOP_S, - SCRSOUND_SAWMILL_LOOP_L, - _SCRSOUND_DOG_FOOD_FACTORY_S, - _SCRSOUND_DOG_FOOD_FACTORY_L, - _SCRSOUND_LAUNDERETTE_1, - _SCRSOUND_LAUNDERETTE_2, - _SCRSOUND_RESTAURANT_CHINATOWN_S, - _SCRSOUND_RESTAURANT_CHINATOWN_L, - _SCRSOUND_RESTAURANT_ITALY_S, - _SCRSOUND_RESTAURANT_ITALY_L, - _SCRSOUND_RESTAURANT_GENERIC_1_S, - _SCRSOUND_RESTAURANT_GENERIC_1_L, - _SCRSOUND_RESTAURANT_GENERIC_2_S, - _SCRSOUND_RESTAURANT_GENERIC_2_L, - _SCRSOUND_AIRPORT_ANNOUNCEMENT_S, - _SCRSOUND_AIRPORT_ANNOUNCEMENT_L, - _SCRSOUND_SHOP_LOOP_1, - _SCRSOUND_SHOP_LOOP_2, - _SCRSOUND_CINEMA_S, - _SCRSOUND_CINEMA_L, - _SCRSOUND_DOCKS_FOGHORN_S, - _SCRSOUND_DOCKS_FOGHORN_L, - _SCRSOUND_HOME_S, - _SCRSOUND_HOME_L, - _SCRSOUND_PIANO_BAR, - _SCRSOUND_CLUB, - SCRSOUND_PORN_CINEMA_1_S, - _SCRSOUND_PORN_CINEMA_1_L, - SCRSOUND_PORN_CINEMA_2_S, - _SCRSOUND_PORN_CINEMA_2_L, - SCRSOUND_PORN_CINEMA_3_S, - _SCRSOUND_PORN_CINEMA_3_L, - _SCRSOUND_BANK_ALARM_LOOP_S, - SCRSOUND_BANK_ALARM_LOOP_L, - _SCRSOUND_POLICE_BALL_LOOP_S, - SCRSOUND_POLICE_BALL_LOOP_L, - _SCRSOUND_RAVE_LOOP_INDUSTRIAL_S, - SCRSOUND_RAVE_LOOP_INDUSTRIAL_L, - _SCRSOUND_UNK_74, - _SCRSOUND_UNK_75, - _SCRSOUND_POLICE_CELL_BEATING_LOOP_S, - SCRSOUND_POLICE_CELL_BEATING_LOOP_L, - SCRSOUND_INJURED_PED_MALE_OUCH_S, - SCRSOUND_INJURED_PED_MALE_OUCH_L, - SCRSOUND_INJURED_PED_FEMALE_OUCH_S, - SCRSOUND_INJURED_PED_FEMALE_OUCH_L, - SCRSOUND_EVIDENCE_PICKUP, - SCRSOUND_UNLOAD_GOLD, - _SCRSOUND_RAVE_INDUSTRIAL_S, - _SCRSOUND_RAVE_INDUSTRIAL_L, - _SCRSOUND_RAVE_COMMERCIAL_S, - _SCRSOUND_RAVE_COMMERCIAL_L, - _SCRSOUND_RAVE_SUBURBAN_S, - _SCRSOUND_RAVE_SUBURBAN_L, - _SCRSOUND_GROAN_S, - _SCRSOUND_GROAN_L, - SCRSOUND_GATE_START_CLUNK, - SCRSOUND_GATE_STOP_CLUNK, - SCRSOUND_PART_MISSION_COMPLETE, - SCRSOUND_CHUNKY_RUN_SHOUT, - SCRSOUND_SECURITY_GUARD_RUN_AWAY_SHOUT, - SCRSOUND_RACE_START_1, - SCRSOUND_RACE_START_2, - SCRSOUND_RACE_START_3, - SCRSOUND_RACE_START_GO, - SCRSOUND_SWAT_PED_SHOUT, - SCRSOUND_PRETEND_FIRE_LOOP, - SCRSOUND_AMMUNATION_CHAT_1, - SCRSOUND_AMMUNATION_CHAT_2, - SCRSOUND_AMMUNATION_CHAT_3, - _SCRSOUND_BULLET_WALL_1, - _SCRSOUND_BULLET_WALL_2, - _SCRSOUND_BULLET_WALL_3, - _SCRSOUND_UNK_109, - _SCRSOUND_GLASSFX2_1, - _SCRSOUND_GLASSFX2_2, - _SCRSOUND_PHONE_RING, - _SCRSOUND_UNK_113, - _SCRSOUND_GLASS_SMASH_1, - _SCRSOUND_GLASS_SMASH_2, - _SCRSOUND_GLASS_CRACK, - _SCRSOUND_GLASS_SHARD, - _SCRSOUND_WOODEN_BOX_SMASH, - _SCRSOUND_CARDBOARD_BOX_SMASH, - _SCRSOUND_COL_CAR, - _SCRSOUND_TYRE_BUMP, - _SCRSOUND_BULLET_SHELL_HIT_GROUND_1, - _SCRSOUND_BULLET_SHELL_HIT_GROUND_2, - TOTAL_SCRSOUNDS, - SCRSOUND_INVALID -}; - class cAudioScriptObject { public: diff --git a/src/audio/DMAudio.cpp b/src/audio/DMAudio.cpp index 888081b7..18d13c9d 100644 --- a/src/audio/DMAudio.cpp +++ b/src/audio/DMAudio.cpp @@ -29,7 +29,7 @@ cDMAudio::Service(void) } int32 -cDMAudio::CreateEntity(int32 type, void *UID) +cDMAudio::CreateEntity(eAudioType type, void *UID) { return AudioManager.CreateEntity(type, (CPhysical *)UID); } @@ -82,7 +82,7 @@ cDMAudio::SetEffectsFadeVol(uint8 volume) uint8 vol = volume; if ( vol > MAX_VOLUME ) vol = MAX_VOLUME; - AudioManager.SetEffectsFadeVolume(vol); + AudioManager.SetEffectsFadeVol(vol); } void @@ -91,7 +91,7 @@ cDMAudio::SetMusicFadeVol(uint8 volume) uint8 vol = volume; if ( vol > MAX_VOLUME ) vol = MAX_VOLUME; - AudioManager.SetMusicFadeVolume(vol); + AudioManager.SetMusicFadeVol(vol); } uint8 diff --git a/src/audio/DMAudio.h b/src/audio/DMAudio.h index 052fdb81..e1a18830 100644 --- a/src/audio/DMAudio.h +++ b/src/audio/DMAudio.h @@ -20,7 +20,7 @@ public: void Terminate(void); void Service(void); - int32 CreateEntity(int32 type, void *UID); + int32 CreateEntity(eAudioType type, void *UID); void DestroyEntity(int32 audioEntity); void SetEntityStatus(int32 audioEntity, uint8 status); void PlayOneShot(int32 audioEntity, uint16 oneShot, float volume); diff --git a/src/audio/MusicManager.cpp b/src/audio/MusicManager.cpp index 841573a9..afe31bf0 100644 --- a/src/audio/MusicManager.cpp +++ b/src/audio/MusicManager.cpp @@ -21,8 +21,6 @@ int32 gNumRetunePresses; int32 gRetuneCounter; bool bHasStarted; -const int maxVolume = 127; - cMusicManager::cMusicManager() { m_bIsInitialised = false; @@ -376,7 +374,7 @@ cMusicManager::Service() if (!m_bIsInitialised || m_bDisabled) return; if (m_nMusicMode == MUSICMODE_CUTSCENE) { - SampleManager.SetStreamedVolumeAndPan(maxVolume, 63, 1, 0); + SampleManager.SetStreamedVolumeAndPan(MAX_VOLUME, 63, 1, 0); return; } @@ -677,7 +675,7 @@ cMusicManager::PreloadCutSceneMusic(uint8 track) while (SampleManager.IsStreamPlaying(0)) SampleManager.StopStreamedFile(0); SampleManager.PreloadStreamedFile(track, 0); - SampleManager.SetStreamedVolumeAndPan(maxVolume, 63, 1, 0); + SampleManager.SetStreamedVolumeAndPan(MAX_VOLUME, 63, 1, 0); m_nCurrentStreamedSound = track; } } diff --git a/src/audio/PoliceRadio.cpp b/src/audio/PoliceRadio.cpp index abacb425..c8baec25 100644 --- a/src/audio/PoliceRadio.cpp +++ b/src/audio/PoliceRadio.cpp @@ -14,7 +14,6 @@ #include "Zones.h" #include "sampman.h" -const int maxVolume = 127; const int channels = ARRAY_SIZE(cAudioManager::m_asActiveSamples); const int policeChannel = channels + 1; @@ -227,7 +226,7 @@ cAudioManager::ServicePoliceRadioChannel(int32 wantedLevel) } } else if (!SampleManager.GetChannelUsedFlag(policeChannel)) { SampleManager.PreloadStreamedFile(g_nMissionAudioSfx, 1); - SampleManager.SetStreamedVolumeAndPan(maxVolume, 63, 1, 1); + SampleManager.SetStreamedVolumeAndPan(MAX_VOLUME, 63, 1, 1); SampleManager.StartPreloadedStreamedFile(1); g_nMissionAudioPlayingStatus = 1; bMissionAudioPhysicalPlayingStatus = 0; diff --git a/src/audio/oal/aldlist.cpp b/src/audio/oal/aldlist.cpp index 458b7c80..3e86b1d7 100644 --- a/src/audio/oal/aldlist.cpp +++ b/src/audio/oal/aldlist.cpp @@ -35,15 +35,13 @@ */ ALDeviceList::ALDeviceList() { - ALDEVICEINFO ALDeviceInfo; char *devices; int index; const char *defaultDeviceName; const char *actualDeviceName; // DeviceInfo vector stores, for each enumerated device, it's device name, selection status, spec version #, and extension support - vDeviceInfo.empty(); - vDeviceInfo.reserve(10); + nNumOfDevices = 0; defaultDeviceIndex = 0; @@ -65,51 +63,49 @@ ALDeviceList::ALDeviceList() // if new actual device name isn't already in the list, then add it... actualDeviceName = alcGetString(device, ALC_DEVICE_SPECIFIER); bool bNewName = true; - for (int i = 0; i < GetNumDevices(); i++) { + for (unsigned int i = 0; i < GetNumDevices(); i++) { if (strcmp(GetDeviceName(i), actualDeviceName) == 0) { bNewName = false; } } if ((bNewName) && (actualDeviceName != NULL) && (strlen(actualDeviceName) > 0)) { - memset(&ALDeviceInfo, 0, sizeof(ALDEVICEINFO)); + ALDEVICEINFO ALDeviceInfo; ALDeviceInfo.bSelected = true; - ALDeviceInfo.strDeviceName.assign(actualDeviceName, strlen(actualDeviceName)); + ALDeviceInfo.strDeviceName = actualDeviceName; alcGetIntegerv(device, ALC_MAJOR_VERSION, sizeof(int), &ALDeviceInfo.iMajorVersion); alcGetIntegerv(device, ALC_MINOR_VERSION, sizeof(int), &ALDeviceInfo.iMinorVersion); - ALDeviceInfo.pvstrExtensions = new std::vector; - // Check for ALC Extensions if (alcIsExtensionPresent(device, "ALC_EXT_CAPTURE") == AL_TRUE) - ALDeviceInfo.pvstrExtensions->push_back("ALC_EXT_CAPTURE"); + ALDeviceInfo.Extensions |= ADEXT_EXT_CAPTURE; if (alcIsExtensionPresent(device, "ALC_EXT_EFX") == AL_TRUE) - ALDeviceInfo.pvstrExtensions->push_back("ALC_EXT_EFX"); + ALDeviceInfo.Extensions |= ADEXT_EXT_EFX; // Check for AL Extensions if (alIsExtensionPresent("AL_EXT_OFFSET") == AL_TRUE) - ALDeviceInfo.pvstrExtensions->push_back("AL_EXT_OFFSET"); + ALDeviceInfo.Extensions |= ADEXT_EXT_OFFSET; if (alIsExtensionPresent("AL_EXT_LINEAR_DISTANCE") == AL_TRUE) - ALDeviceInfo.pvstrExtensions->push_back("AL_EXT_LINEAR_DISTANCE"); + ALDeviceInfo.Extensions |= ADEXT_EXT_LINEAR_DISTANCE; if (alIsExtensionPresent("AL_EXT_EXPONENT_DISTANCE") == AL_TRUE) - ALDeviceInfo.pvstrExtensions->push_back("AL_EXT_EXPONENT_DISTANCE"); + ALDeviceInfo.Extensions |= ADEXT_EXT_EXPONENT_DISTANCE; if (alIsExtensionPresent("EAX2.0") == AL_TRUE) - ALDeviceInfo.pvstrExtensions->push_back("EAX2.0"); + ALDeviceInfo.Extensions |= ADEXT_EAX2; if (alIsExtensionPresent("EAX3.0") == AL_TRUE) - ALDeviceInfo.pvstrExtensions->push_back("EAX3.0"); + ALDeviceInfo.Extensions |= ADEXT_EAX3; if (alIsExtensionPresent("EAX4.0") == AL_TRUE) - ALDeviceInfo.pvstrExtensions->push_back("EAX4.0"); + ALDeviceInfo.Extensions |= ADEXT_EAX4; if (alIsExtensionPresent("EAX5.0") == AL_TRUE) - ALDeviceInfo.pvstrExtensions->push_back("EAX5.0"); + ALDeviceInfo.Extensions |= ADEXT_EAX5; if (alIsExtensionPresent("EAX-RAM") == AL_TRUE) - ALDeviceInfo.pvstrExtensions->push_back("EAX-RAM"); + ALDeviceInfo.Extensions |= ADEXT_EAX_RAM; // Get Source Count ALDeviceInfo.uiSourceCount = GetMaxNumSources(); - vDeviceInfo.push_back(ALDeviceInfo); + aDeviceInfo[nNumOfDevices++] = ALDeviceInfo; } alcMakeContextCurrent(NULL); alcDestroyContext(context); @@ -129,31 +125,23 @@ ALDeviceList::ALDeviceList() */ ALDeviceList::~ALDeviceList() { - for (unsigned int i = 0; i < vDeviceInfo.size(); i++) { - if (vDeviceInfo[i].pvstrExtensions) { - vDeviceInfo[i].pvstrExtensions->empty(); - delete vDeviceInfo[i].pvstrExtensions; - } - } - - vDeviceInfo.empty(); } /* * Returns the number of devices in the complete device list */ -int ALDeviceList::GetNumDevices() +unsigned int ALDeviceList::GetNumDevices() { - return (int)vDeviceInfo.size(); + return nNumOfDevices; } /* * Returns the device name at an index in the complete device list */ -char * ALDeviceList::GetDeviceName(int index) +const char * ALDeviceList::GetDeviceName(unsigned int index) { if (index < GetNumDevices()) - return (char *)vDeviceInfo[index].strDeviceName.c_str(); + return aDeviceInfo[index].strDeviceName; else return NULL; } @@ -161,13 +149,13 @@ char * ALDeviceList::GetDeviceName(int index) /* * Returns the major and minor version numbers for a device at a specified index in the complete list */ -void ALDeviceList::GetDeviceVersion(int index, int *major, int *minor) +void ALDeviceList::GetDeviceVersion(unsigned int index, int *major, int *minor) { if (index < GetNumDevices()) { if (major) - *major = vDeviceInfo[index].iMajorVersion; + *major = aDeviceInfo[index].iMajorVersion; if (minor) - *minor = vDeviceInfo[index].iMinorVersion; + *minor = aDeviceInfo[index].iMinorVersion; } return; } @@ -175,10 +163,10 @@ void ALDeviceList::GetDeviceVersion(int index, int *major, int *minor) /* * Returns the maximum number of Sources that can be generate on the given device */ -unsigned int ALDeviceList::GetMaxNumSources(int index) +unsigned int ALDeviceList::GetMaxNumSources(unsigned int index) { if (index < GetNumDevices()) - return vDeviceInfo[index].uiSourceCount; + return aDeviceInfo[index].uiSourceCount; else return 0; } @@ -186,20 +174,9 @@ unsigned int ALDeviceList::GetMaxNumSources(int index) /* * Checks if the extension is supported on the given device */ -bool ALDeviceList::IsExtensionSupported(int index, const char *szExtName) +bool ALDeviceList::IsExtensionSupported(int index, unsigned short ext) { - bool bReturn = false; - - if (index < GetNumDevices()) { - for (unsigned int i = 0; i < vDeviceInfo[index].pvstrExtensions->size(); i++) { - if (!_stricmp(vDeviceInfo[index].pvstrExtensions->at(i).c_str(), szExtName)) { - bReturn = true; - break; - } - } - } - - return bReturn; + return !!(aDeviceInfo[index].Extensions & ext); } /* @@ -216,10 +193,10 @@ int ALDeviceList::GetDefaultDevice() void ALDeviceList::FilterDevicesMinVer(int major, int minor) { int dMajor, dMinor; - for (unsigned int i = 0; i < vDeviceInfo.size(); i++) { + for (unsigned int i = 0; i < nNumOfDevices; i++) { GetDeviceVersion(i, &dMajor, &dMinor); if ((dMajor < major) || ((dMajor == major) && (dMinor < minor))) { - vDeviceInfo[i].bSelected = false; + aDeviceInfo[i].bSelected = false; } } } @@ -230,10 +207,10 @@ void ALDeviceList::FilterDevicesMinVer(int major, int minor) void ALDeviceList::FilterDevicesMaxVer(int major, int minor) { int dMajor, dMinor; - for (unsigned int i = 0; i < vDeviceInfo.size(); i++) { + for (unsigned int i = 0; i < nNumOfDevices; i++) { GetDeviceVersion(i, &dMajor, &dMinor); if ((dMajor > major) || ((dMajor == major) && (dMinor > minor))) { - vDeviceInfo[i].bSelected = false; + aDeviceInfo[i].bSelected = false; } } } @@ -241,20 +218,12 @@ void ALDeviceList::FilterDevicesMaxVer(int major, int minor) /* * Deselects device which don't support the given extension name */ -void ALDeviceList::FilterDevicesExtension(char *szExtName) +void +ALDeviceList::FilterDevicesExtension(unsigned short ext) { - bool bFound; - - for (unsigned int i = 0; i < vDeviceInfo.size(); i++) { - bFound = false; - for (unsigned int j = 0; j < vDeviceInfo[i].pvstrExtensions->size(); j++) { - if (!_stricmp(vDeviceInfo[i].pvstrExtensions->at(j).c_str(), szExtName)) { - bFound = true; - break; - } - } - if (!bFound) - vDeviceInfo[i].bSelected = false; + for (unsigned int i = 0; i < nNumOfDevices; i++) { + if (!IsExtensionSupported(i, ext)) + aDeviceInfo[i].bSelected = false; } } @@ -263,8 +232,8 @@ void ALDeviceList::FilterDevicesExtension(char *szExtName) */ void ALDeviceList::ResetFilters() { - for (int i = 0; i < GetNumDevices(); i++) { - vDeviceInfo[i].bSelected = true; + for (unsigned int i = 0; i < GetNumDevices(); i++) { + aDeviceInfo[i].bSelected = true; } filterIndex = 0; } @@ -274,10 +243,10 @@ void ALDeviceList::ResetFilters() */ int ALDeviceList::GetFirstFilteredDevice() { - int i; + unsigned int i; for (i = 0; i < GetNumDevices(); i++) { - if (vDeviceInfo[i].bSelected == true) { + if (aDeviceInfo[i].bSelected == true) { break; } } @@ -290,10 +259,10 @@ int ALDeviceList::GetFirstFilteredDevice() */ int ALDeviceList::GetNextFilteredDevice() { - int i; + unsigned int i; for (i = filterIndex; i < GetNumDevices(); i++) { - if (vDeviceInfo[i].bSelected == true) { + if (aDeviceInfo[i].bSelected == true) { break; } } diff --git a/src/audio/oal/aldlist.h b/src/audio/oal/aldlist.h index 694c9d01..417bd314 100644 --- a/src/audio/oal/aldlist.h +++ b/src/audio/oal/aldlist.h @@ -5,38 +5,58 @@ #ifdef AUDIO_OAL #pragma warning(disable: 4786) //disable warning "identifier was truncated to '255' characters in the browser information" -#include -#include -typedef struct +enum { - std::string strDeviceName; + ADEXT_EXT_CAPTURE = (1 << 0), + ADEXT_EXT_EFX = (1 << 1), + ADEXT_EXT_OFFSET = (1 << 2), + ADEXT_EXT_LINEAR_DISTANCE = (1 << 3), + ADEXT_EXT_EXPONENT_DISTANCE = (1 << 4), + ADEXT_EAX2 = (1 << 5), + ADEXT_EAX3 = (1 << 6), + ADEXT_EAX4 = (1 << 7), + ADEXT_EAX5 = (1 << 8), + ADEXT_EAX_RAM = (1 << 9), +}; + +struct ALDEVICEINFO { + const char *strDeviceName; int iMajorVersion; int iMinorVersion; unsigned int uiSourceCount; - std::vector *pvstrExtensions; + unsigned short Extensions; bool bSelected; -} ALDEVICEINFO, *LPALDEVICEINFO; + + ALDEVICEINFO() : iMajorVersion(0), iMinorVersion(0), uiSourceCount(0), bSelected(false) + { + strDeviceName = NULL; + Extensions = 0; + } +}; + +typedef ALDEVICEINFO *LPALDEVICEINFO; class ALDeviceList { private: - std::vector vDeviceInfo; + ALDEVICEINFO aDeviceInfo[64]; + unsigned int nNumOfDevices; int defaultDeviceIndex; int filterIndex; public: ALDeviceList (); ~ALDeviceList (); - int GetNumDevices(); - char *GetDeviceName(int index); - void GetDeviceVersion(int index, int *major, int *minor); - unsigned int GetMaxNumSources(int index); - bool IsExtensionSupported(int index, const char *szExtName); + unsigned int GetNumDevices(); + const char *GetDeviceName(unsigned int index); + void GetDeviceVersion(unsigned int index, int *major, int *minor); + unsigned int GetMaxNumSources(unsigned int index); + bool IsExtensionSupported(int index, unsigned short ext); int GetDefaultDevice(); void FilterDevicesMinVer(int major, int minor); void FilterDevicesMaxVer(int major, int minor); - void FilterDevicesExtension(char *szExtName); + void FilterDevicesExtension(unsigned short ext); void ResetFilters(); int GetFirstFilteredDevice(); int GetNextFilteredDevice(); diff --git a/src/audio/oal/channel.cpp b/src/audio/oal/channel.cpp index 6fe1d856..731e3581 100644 --- a/src/audio/oal/channel.cpp +++ b/src/audio/oal/channel.cpp @@ -1,7 +1,7 @@ -#include "channel.h" +#include "common.h" #ifdef AUDIO_OAL -#include "common.h" +#include "channel.h" #include "sampman.h" #ifndef _WIN32 diff --git a/src/audio/oal/channel.h b/src/audio/oal/channel.h index 4dd09ca1..0c86bdc6 100644 --- a/src/audio/oal/channel.h +++ b/src/audio/oal/channel.h @@ -1,5 +1,4 @@ #pragma once -#include "common.h" #ifdef AUDIO_OAL #include "oal/oal_utils.h" diff --git a/src/audio/oal/oal_utils.cpp b/src/audio/oal/oal_utils.cpp index 4119672f..e16de572 100644 --- a/src/audio/oal/oal_utils.cpp +++ b/src/audio/oal/oal_utils.cpp @@ -1,3 +1,4 @@ +#include "common.h" #include "oal_utils.h" #ifdef AUDIO_OAL diff --git a/src/audio/oal/oal_utils.h b/src/audio/oal/oal_utils.h index af45a944..b89ccf36 100644 --- a/src/audio/oal/oal_utils.h +++ b/src/audio/oal/oal_utils.h @@ -1,5 +1,4 @@ #pragma once -#include "common.h" #ifdef AUDIO_OAL #include "eax.h" diff --git a/src/audio/oal/stream.cpp b/src/audio/oal/stream.cpp index 5a9c7d7d..34518f54 100644 --- a/src/audio/oal/stream.cpp +++ b/src/audio/oal/stream.cpp @@ -1,11 +1,9 @@ -#include "stream.h" +#include "common.h" #ifdef AUDIO_OAL -#include "common.h" +#include "stream.h" #include "sampman.h" -#include -#include #ifdef _WIN32 typedef long ssize_t; #pragma comment( lib, "libsndfile-1.lib" ) @@ -13,6 +11,8 @@ typedef long ssize_t; #else #include "crossplatform.h" #endif +#include +#include class CSndFile : public IDecoder { diff --git a/src/audio/oal/stream.h b/src/audio/oal/stream.h index f1e5f458..456c080a 100644 --- a/src/audio/oal/stream.h +++ b/src/audio/oal/stream.h @@ -1,5 +1,4 @@ #pragma once -#include "common.h" #ifdef AUDIO_OAL #include diff --git a/src/audio/sampman.h b/src/audio/sampman.h index d3c82943..621d4015 100644 --- a/src/audio/sampman.h +++ b/src/audio/sampman.h @@ -3,7 +3,7 @@ #include "AudioSamples.h" #define MAX_VOLUME 127 -#define MAX_FREQ 22050 +#define MAX_FREQ DIGITALRATE struct tSample { int32 nOffset; diff --git a/src/audio/sampman_miles.cpp b/src/audio/sampman_miles.cpp index a2a206a4..d625ac35 100644 --- a/src/audio/sampman_miles.cpp +++ b/src/audio/sampman_miles.cpp @@ -1445,7 +1445,7 @@ cSampleManager::IsSampleBankLoaded(uint8 nBank) bool cSampleManager::IsPedCommentLoaded(uint32 nComment) { - uint8 slot; + int8 slot; for ( int32 i = 0; i < _TODOCONST(3); i++ ) { @@ -1464,11 +1464,15 @@ cSampleManager::IsPedCommentLoaded(uint32 nComment) int32 cSampleManager::_GetPedCommentSlot(uint32 nComment) { - uint8 slot; + int8 slot; for ( int32 i = 0; i < _TODOCONST(3); i++ ) { slot = nCurrentPedSlot - i - 1; +#ifdef FIX_BUGS + if (slot < 0) + slot += ARRAY_SIZE(nPedSlotSfx); +#endif if ( nComment == nPedSlotSfx[slot] ) return slot; } diff --git a/src/audio/sampman_null.cpp b/src/audio/sampman_null.cpp new file mode 100644 index 00000000..6ec8a521 --- /dev/null +++ b/src/audio/sampman_null.cpp @@ -0,0 +1,368 @@ +#include "common.h" +#if !defined(AUDIO_OAL) && !defined(AUDIO_MSS) +#include "sampman.h" +#include "AudioManager.h" + +cSampleManager SampleManager; +bool _bSampmanInitialised = false; + +uint32 BankStartOffset[MAX_SAMPLEBANKS]; +uint32 nNumMP3s; + +cSampleManager::cSampleManager(void) +{ + ; +} + +cSampleManager::~cSampleManager(void) +{ + +} + +void cSampleManager::SetSpeakerConfig(int32 nConfig) +{ + +} + +uint32 cSampleManager::GetMaximumSupportedChannels(void) +{ + return MAXCHANNELS; +} + +uint32 cSampleManager::GetNum3DProvidersAvailable() +{ + return 1; +} + +void cSampleManager::SetNum3DProvidersAvailable(uint32 num) +{ + +} + +char *cSampleManager::Get3DProviderName(uint8 id) +{ + static char name[64] = "NULL"; + return name; +} + +void cSampleManager::Set3DProviderName(uint8 id, char *name) +{ + +} + +int8 cSampleManager::GetCurrent3DProviderIndex(void) +{ + return 0; +} + +int8 cSampleManager::SetCurrent3DProvider(uint8 nProvider) +{ + return 0; +} + +bool +cSampleManager::IsMP3RadioChannelAvailable(void) +{ + return nNumMP3s != 0; +} + + +void cSampleManager::ReleaseDigitalHandle(void) +{ +} + +void cSampleManager::ReacquireDigitalHandle(void) +{ +} + +bool +cSampleManager::Initialise(void) +{ + return true; +} + +void +cSampleManager::Terminate(void) +{ + +} + +bool cSampleManager::CheckForAnAudioFileOnCD(void) +{ + return true; +} + +char cSampleManager::GetCDAudioDriveLetter(void) +{ + return '\0'; +} + +void +cSampleManager::UpdateEffectsVolume(void) +{ + +} + +void +cSampleManager::SetEffectsMasterVolume(uint8 nVolume) +{ +} + +void +cSampleManager::SetMusicMasterVolume(uint8 nVolume) +{ +} + +void +cSampleManager::SetEffectsFadeVolume(uint8 nVolume) +{ +} + +void +cSampleManager::SetMusicFadeVolume(uint8 nVolume) +{ +} + +void +cSampleManager::SetMonoMode(uint8 nMode) +{ +} + +bool +cSampleManager::LoadSampleBank(uint8 nBank) +{ + ASSERT( nBank < MAX_SAMPLEBANKS ); + return false; +} + +void +cSampleManager::UnloadSampleBank(uint8 nBank) +{ + ASSERT( nBank < MAX_SAMPLEBANKS ); +} + +bool +cSampleManager::IsSampleBankLoaded(uint8 nBank) +{ + ASSERT( nBank < MAX_SAMPLEBANKS ); + + return false; +} + +bool +cSampleManager::IsPedCommentLoaded(uint32 nComment) +{ + ASSERT( nComment < TOTAL_AUDIO_SAMPLES ); + + return false; +} + + +int32 +cSampleManager::_GetPedCommentSlot(uint32 nComment) +{ + return -1; +} + +bool +cSampleManager::LoadPedComment(uint32 nComment) +{ + ASSERT( nComment < TOTAL_AUDIO_SAMPLES ); + return false; +} + +int32 +cSampleManager::GetBankContainingSound(uint32 offset) +{ + return SAMPLEBANK_INVALID; +} + +int32 +cSampleManager::GetSampleBaseFrequency(uint32 nSample) +{ + ASSERT( nSample < TOTAL_AUDIO_SAMPLES ); + return 0; +} + +int32 +cSampleManager::GetSampleLoopStartOffset(uint32 nSample) +{ + ASSERT( nSample < TOTAL_AUDIO_SAMPLES ); + return 0; +} + +int32 +cSampleManager::GetSampleLoopEndOffset(uint32 nSample) +{ + ASSERT( nSample < TOTAL_AUDIO_SAMPLES ); + return 0; +} + +uint32 +cSampleManager::GetSampleLength(uint32 nSample) +{ + ASSERT( nSample < TOTAL_AUDIO_SAMPLES ); + return 0; +} + +bool cSampleManager::UpdateReverb(void) +{ + return false; +} + +void +cSampleManager::SetChannelReverbFlag(uint32 nChannel, uint8 nReverbFlag) +{ + ASSERT( nChannel < MAXCHANNELS+MAX2DCHANNELS ); +} + +bool +cSampleManager::InitialiseChannel(uint32 nChannel, uint32 nSfx, uint8 nBank) +{ + ASSERT( nChannel < MAXCHANNELS+MAX2DCHANNELS ); + return false; +} + +void +cSampleManager::SetChannelEmittingVolume(uint32 nChannel, uint32 nVolume) +{ + ASSERT( nChannel != CHANNEL2D ); + ASSERT( nChannel < MAXCHANNELS+MAX2DCHANNELS ); +} + +void +cSampleManager::SetChannel3DPosition(uint32 nChannel, float fX, float fY, float fZ) +{ + ASSERT( nChannel != CHANNEL2D ); + ASSERT( nChannel < MAXCHANNELS+MAX2DCHANNELS ); +} + +void +cSampleManager::SetChannel3DDistances(uint32 nChannel, float fMax, float fMin) +{ + ASSERT( nChannel != CHANNEL2D ); + ASSERT( nChannel < MAXCHANNELS+MAX2DCHANNELS ); +} + +void +cSampleManager::SetChannelVolume(uint32 nChannel, uint32 nVolume) +{ + ASSERT( nChannel == CHANNEL2D ); + ASSERT( nChannel < MAXCHANNELS+MAX2DCHANNELS ); +} + +void +cSampleManager::SetChannelPan(uint32 nChannel, uint32 nPan) +{ + ASSERT(nChannel == CHANNEL2D); + ASSERT( nChannel < MAXCHANNELS+MAX2DCHANNELS ); +} + +void +cSampleManager::SetChannelFrequency(uint32 nChannel, uint32 nFreq) +{ + ASSERT( nChannel < MAXCHANNELS+MAX2DCHANNELS ); +} + +void +cSampleManager::SetChannelLoopPoints(uint32 nChannel, uint32 nLoopStart, int32 nLoopEnd) +{ + ASSERT( nChannel < MAXCHANNELS+MAX2DCHANNELS ); +} + +void +cSampleManager::SetChannelLoopCount(uint32 nChannel, uint32 nLoopCount) +{ + ASSERT( nChannel < MAXCHANNELS+MAX2DCHANNELS ); +} + +bool +cSampleManager::GetChannelUsedFlag(uint32 nChannel) +{ + ASSERT( nChannel < MAXCHANNELS+MAX2DCHANNELS ); + + return false; +} + +void +cSampleManager::StartChannel(uint32 nChannel) +{ + ASSERT( nChannel < MAXCHANNELS+MAX2DCHANNELS ); +} + +void +cSampleManager::StopChannel(uint32 nChannel) +{ + ASSERT( nChannel < MAXCHANNELS+MAX2DCHANNELS ); +} + +void +cSampleManager::PreloadStreamedFile(uint8 nFile, uint8 nStream) +{ + ASSERT( nStream < MAX_STREAMS ); +} + +void +cSampleManager::PauseStream(uint8 nPauseFlag, uint8 nStream) +{ + ASSERT( nStream < MAX_STREAMS ); +} + +void +cSampleManager::StartPreloadedStreamedFile(uint8 nStream) +{ + ASSERT( nStream < MAX_STREAMS ); +} + +bool +cSampleManager::StartStreamedFile(uint8 nFile, uint32 nPos, uint8 nStream) +{ + ASSERT( nStream < MAX_STREAMS ); + + return false; +} + +void +cSampleManager::StopStreamedFile(uint8 nStream) +{ + ASSERT( nStream < MAX_STREAMS ); +} + +int32 +cSampleManager::GetStreamedFilePosition(uint8 nStream) +{ + ASSERT( nStream < MAX_STREAMS ); + + return 0; +} + +void +cSampleManager::SetStreamedVolumeAndPan(uint8 nVolume, uint8 nPan, uint8 nEffectFlag, uint8 nStream) +{ + ASSERT( nStream < MAX_STREAMS ); +} + +int32 +cSampleManager::GetStreamedFileLength(uint8 nStream) +{ + ASSERT( nStream < TOTAL_STREAMED_SOUNDS ); + + return 1; +} + +bool +cSampleManager::IsStreamPlaying(uint8 nStream) +{ + ASSERT( nStream < MAX_STREAMS ); + + return false; +} + +bool +cSampleManager::InitialiseSampleBanks(void) +{ + + return true; +} + +#endif diff --git a/src/audio/sampman_oal.cpp b/src/audio/sampman_oal.cpp index 30efd7f5..1952f370 100644 --- a/src/audio/sampman_oal.cpp +++ b/src/audio/sampman_oal.cpp @@ -174,10 +174,10 @@ add_providers() } if ( alGetEnumValue("AL_EFFECT_EAXREVERB") != 0 - || pDeviceList->IsExtensionSupported(i, "EAX2.0") - || pDeviceList->IsExtensionSupported(i, "EAX3.0") - || pDeviceList->IsExtensionSupported(i, "EAX4.0") - || pDeviceList->IsExtensionSupported(i, "EAX5.0") ) + || pDeviceList->IsExtensionSupported(i, ADEXT_EAX2) + || pDeviceList->IsExtensionSupported(i, ADEXT_EAX3) + || pDeviceList->IsExtensionSupported(i, ADEXT_EAX4) + || pDeviceList->IsExtensionSupported(i, ADEXT_EAX5) ) { if ( n < MAXPROVIDERS ) { @@ -775,7 +775,7 @@ cSampleManager::IsPedCommentLoaded(uint32 nComment) { ASSERT( nComment < TOTAL_AUDIO_SAMPLES ); - uint8 slot; + int8 slot; for ( int32 i = 0; i < _TODOCONST(3); i++ ) { @@ -795,11 +795,15 @@ cSampleManager::IsPedCommentLoaded(uint32 nComment) int32 cSampleManager::_GetPedCommentSlot(uint32 nComment) { - uint8 slot; + int8 slot; for (int32 i = 0; i < _TODOCONST(3); i++) { slot = nCurrentPedSlot - i - 1; +#ifdef FIX_BUGS + if (slot < 0) + slot += ARRAY_SIZE(nPedSlotSfx); +#endif if (nComment == nPedSlotSfx[slot]) return slot; } diff --git a/src/audio/soundlist.h b/src/audio/soundlist.h index 64d7dbcb..6d1ff6e3 100644 --- a/src/audio/soundlist.h +++ b/src/audio/soundlist.h @@ -1,301 +1,303 @@ #pragma once -enum eSound : int16 +enum eSound : uint16 { SOUND_CAR_DOOR_CLOSE_BONNET = 0, - SOUND_CAR_DOOR_CLOSE_BUMPER = 1, - SOUND_CAR_DOOR_CLOSE_FRONT_LEFT = 2, - SOUND_CAR_DOOR_CLOSE_FRONT_RIGHT = 3, - SOUND_CAR_DOOR_CLOSE_BACK_LEFT = 4, - SOUND_CAR_DOOR_CLOSE_BACK_RIGHT = 5, - SOUND_CAR_DOOR_OPEN_BONNET = 6, - SOUND_CAR_DOOR_OPEN_BUMPER = 7, - SOUND_CAR_DOOR_OPEN_FRONT_LEFT = 8, - SOUND_CAR_DOOR_OPEN_FRONT_RIGHT = 9, - SOUND_CAR_DOOR_OPEN_BACK_LEFT = 10, - SOUND_CAR_DOOR_OPEN_BACK_RIGHT = 11, - SOUND_CAR_WINDSHIELD_CRACK = 12, - SOUND_CAR_JUMP = 13, - SOUND_E = 14, - SOUND_F = 15, - SOUND_CAR_ENGINE_START = 16, - SOUND_CAR_LIGHT_BREAK = 17, - SOUND_CAR_HYDRAULIC_1 = 18, - SOUND_CAR_HYDRAULIC_2 = 19, - SOUND_CAR_HYDRAULIC_3 = 20, - SOUND_CAR_JERK = 21, - SOUND_CAR_SPLASH = 22, - SOUND_17 = 23, - SOUND_18 = 24, - SOUND_19 = 25, - SOUND_CAR_TANK_TURRET_ROTATE = 26, - SOUND_CAR_BOMB_TICK = 27, - SOUND_PLANE_ON_GROUND = 28, - SOUND_STEP_START = 29, - SOUND_STEP_END = 30, - SOUND_FALL_LAND = 31, - SOUND_FALL_COLLAPSE = 32, - SOUND_FIGHT_PUNCH_33 = 33, - SOUND_FIGHT_KICK_34 = 34, - SOUND_FIGHT_HEADBUTT_35 = 35, - SOUND_FIGHT_PUNCH_36 = 36, - SOUND_FIGHT_PUNCH_37 = 37, - SOUND_FIGHT_CLOSE_PUNCH_38 = 38, - SOUND_FIGHT_PUNCH_39 = 39, - SOUND_FIGHT_PUNCH_OR_KICK_BELOW_40 = 40, - SOUND_FIGHT_PUNCH_41 = 41, - SOUND_FIGHT_PUNCH_FROM_BEHIND_42 = 42, - SOUND_FIGHT_KNEE_OR_KICK_43 = 43, - SOUND_FIGHT_KICK_44 = 44, - SOUND_2D = 45, - SOUND_WEAPON_BAT_ATTACK = 46, - SOUND_WEAPON_SHOT_FIRED = 47, - SOUND_WEAPON_RELOAD = 48, - SOUND_WEAPON_AK47_BULLET_ECHO = 49, - SOUND_WEAPON_UZI_BULLET_ECHO = 50, - SOUND_WEAPON_M16_BULLET_ECHO = 51, - SOUND_WEAPON_FLAMETHROWER_FIRE = 52, - SOUND_WEAPON_SNIPER_SHOT_NO_ZOOM = 53, - SOUND_WEAPON_ROCKET_SHOT_NO_ZOOM = 54, - SOUND_WEAPON_HIT_PED = 55, - SOUND_WEAPON_HIT_VEHICLE = 56, - SOUND_GARAGE_NO_MONEY = 57, - SOUND_GARAGE_BAD_VEHICLE = 58, - SOUND_GARAGE_OPENING = 59, - SOUND_GARAGE_BOMB_ALREADY_SET = 60, - SOUND_GARAGE_BOMB1_SET = 61, - SOUND_GARAGE_BOMB2_SET = 62, - SOUND_GARAGE_BOMB3_SET = 63, - SOUND_40 = 64, - SOUND_41 = 65, - SOUND_GARAGE_VEHICLE_DECLINED = 66, - SOUND_GARAGE_VEHICLE_ACCEPTED = 67, - SOUND_GARAGE_DOOR_CLOSED = 68, - SOUND_GARAGE_DOOR_OPENED = 69, - SOUND_CRANE_PICKUP = 70, - SOUND_PICKUP_WEAPON_BOUGHT = 71, - SOUND_PICKUP_WEAPON = 72, - SOUND_PICKUP_HEALTH = 73, - SOUND_4A = 74, - SOUND_4B = 75, - SOUND_PICKUP_ADRENALINE = 76, - SOUND_PICKUP_ARMOUR = 77, - SOUND_PICKUP_BONUS = 78, - SOUND_PICKUP_MONEY = 79, - SOUND_PICKUP_HIDDEN_PACKAGE = 80, - SOUND_PICKUP_PACMAN_PILL = 81, - SOUND_PICKUP_PACMAN_PACKAGE = 82, - SOUND_PICKUP_FLOAT_PACKAGE = 83, - SOUND_BOMB_TIMED_ACTIVATED = 84, - SOUND_55 = 85, - SOUND_BOMB_ONIGNITION_ACTIVATED = 86, - SOUND_BOMB_TICK = 87, - SOUND_RAMPAGE_START = 88, - SOUND_RAMPAGE_ONGOING = 89, - SOUND_RAMPAGE_PASSED = 90, - SOUND_RAMPAGE_FAILED = 91, - SOUND_RAMPAGE_KILL = 92, - SOUND_RAMPAGE_CAR_BLOWN = 93, - SOUND_EVIDENCE_PICKUP = 94, - SOUND_UNLOAD_GOLD = 95, - SOUND_PAGER = 96, - SOUND_PED_DEATH = 97, // 103 in VC - SOUND_PED_DAMAGE = 98, // 104 in VC - SOUND_PED_HIT = 99, // 105 in VC - SOUND_PED_LAND = 100, // hopefully 106 in VC - SOUND_PED_BULLET_HIT = 101, - SOUND_PED_BOMBER = 102, - SOUND_PED_BURNING = 103, // 108 in VC - SOUND_PED_ARREST_FBI = 104, - SOUND_PED_ARREST_SWAT = 105, - SOUND_PED_ARREST_COP = 106, - SOUND_PED_HELI_PLAYER_FOUND = 107, - SOUND_PED_HANDS_UP = 108, - SOUND_PED_HANDS_COWER = 109, - SOUND_PED_FLEE_SPRINT = 110, // 120 in VC - SOUND_PED_CAR_JACKING = 111, - SOUND_PED_MUGGING = 112, - SOUND_PED_CAR_JACKED = 113, - SOUND_PED_ROBBED = 114, - SOUND_PED_TAXI_WAIT = 115, // 137 in VC - SOUND_PED_ATTACK = 116, - SOUND_PED_DEFEND = 117, - SOUND_PED_PURSUIT_ARMY = 118, - SOUND_PED_PURSUIT_FBI = 119, - SOUND_PED_PURSUIT_SWAT = 120, - SOUND_PED_PURSUIT_COP = 121, - SOUND_PED_HEALING = 122, - SOUND_PED_7B = 123, - SOUND_PED_LEAVE_VEHICLE = 124, - SOUND_PED_EVADE = 125, // 142 in VC - SOUND_PED_FLEE_RUN = 126, - SOUND_PED_CAR_COLLISION = 127, // 144-145-146 in VC - SOUND_PED_SOLICIT = 128, - SOUND_PED_EXTINGUISHING_FIRE = 129, - SOUND_PED_WAIT_DOUBLEBACK = 130, - SOUND_PED_CHAT_SEXY = 131, - SOUND_PED_CHAT_EVENT = 132, - SOUND_PED_CHAT = 133, - SOUND_PED_BODYCAST_HIT = 134, - SOUND_PED_TAXI_CALL = 135, - SOUND_INJURED_PED_MALE_OUCH = 136, - SOUND_INJURED_PED_FEMALE = 137, - SOUND_INJURED_PED_MALE_PRISON = 138, - SOUND_RACE_START_3 = 139, - SOUND_RACE_START_2 = 140, - SOUND_RACE_START_1 = 141, - SOUND_RACE_START_GO = 142, - SOUND_SPLASH = 143, - SOUND_WATER_FALL = 144, - SOUND_SPLATTER = 145, - SOUND_CAR_PED_COLLISION = 146, - SOUND_CLOCK_TICK = 147, - SOUND_PART_MISSION_COMPLETE = 148, - SOUND_FRONTEND_MENU_STARTING = 149, - SOUND_FRONTEND_MENU_COMPLETED = 150, - SOUND_FRONTEND_MENU_DENIED = 151, - SOUND_FRONTEND_MENU_SUCCESS = 152, - SOUND_FRONTEND_EXIT = 153, - SOUND_9A = 154, - SOUND_9B = 155, - SOUND_FRONTEND_AUDIO_TEST = 156, - SOUND_FRONTEND_FAIL = 157, - SOUND_FRONTEND_NO_RADIO = 158, - SOUND_FRONTEND_RADIO_CHANGE = 159, - SOUND_A0 = 160, - SOUND_AMMUNATION_WELCOME_1 = 161, - SOUND_AMMUNATION_WELCOME_2 = 162, - SOUND_AMMUNATION_WELCOME_3 = 163, - SOUND_LIGHTNING = 164, - SOUND_A5 = 165, - SOUND_TOTAL_SOUNDS = 166, - SOUND_TOTAL_PED_SOUNDS = 167, + SOUND_CAR_DOOR_CLOSE_BUMPER, + SOUND_CAR_DOOR_CLOSE_FRONT_LEFT, + SOUND_CAR_DOOR_CLOSE_FRONT_RIGHT, + SOUND_CAR_DOOR_CLOSE_BACK_LEFT, + SOUND_CAR_DOOR_CLOSE_BACK_RIGHT, + SOUND_CAR_DOOR_OPEN_BONNET, + SOUND_CAR_DOOR_OPEN_BUMPER, + SOUND_CAR_DOOR_OPEN_FRONT_LEFT, + SOUND_CAR_DOOR_OPEN_FRONT_RIGHT, + SOUND_CAR_DOOR_OPEN_BACK_LEFT, + SOUND_CAR_DOOR_OPEN_BACK_RIGHT, + SOUND_CAR_WINDSHIELD_CRACK, + SOUND_CAR_JUMP, + SOUND_E, + SOUND_F, + SOUND_CAR_ENGINE_START, + SOUND_CAR_LIGHT_BREAK, + SOUND_CAR_HYDRAULIC_1, + SOUND_CAR_HYDRAULIC_2, + SOUND_CAR_HYDRAULIC_3, + SOUND_CAR_JERK, + SOUND_CAR_SPLASH, + SOUND_17, + SOUND_18, + SOUND_19, + SOUND_CAR_TANK_TURRET_ROTATE, + SOUND_CAR_BOMB_TICK, + SOUND_PLANE_ON_GROUND, + SOUND_STEP_START, + SOUND_STEP_END, + SOUND_FALL_LAND, + SOUND_FALL_COLLAPSE, + SOUND_FIGHT_PUNCH_33, + SOUND_FIGHT_KICK_34, + SOUND_FIGHT_HEADBUTT_35, + SOUND_FIGHT_PUNCH_36, + SOUND_FIGHT_PUNCH_37, + SOUND_FIGHT_CLOSE_PUNCH_38, + SOUND_FIGHT_PUNCH_39, + SOUND_FIGHT_PUNCH_OR_KICK_BELOW_40, + SOUND_FIGHT_PUNCH_41, + SOUND_FIGHT_PUNCH_FROM_BEHIND_42, + SOUND_FIGHT_KNEE_OR_KICK_43, + SOUND_FIGHT_KICK_44, + SOUND_2D, + SOUND_WEAPON_BAT_ATTACK, + SOUND_WEAPON_SHOT_FIRED, + SOUND_WEAPON_RELOAD, + SOUND_WEAPON_AK47_BULLET_ECHO, + SOUND_WEAPON_UZI_BULLET_ECHO, + SOUND_WEAPON_M16_BULLET_ECHO, + SOUND_WEAPON_FLAMETHROWER_FIRE, + SOUND_WEAPON_SNIPER_SHOT_NO_ZOOM, + SOUND_WEAPON_ROCKET_SHOT_NO_ZOOM, + SOUND_WEAPON_HIT_PED, + SOUND_WEAPON_HIT_VEHICLE, + SOUND_GARAGE_NO_MONEY, + SOUND_GARAGE_BAD_VEHICLE, + SOUND_GARAGE_OPENING, + SOUND_GARAGE_BOMB_ALREADY_SET, + SOUND_GARAGE_BOMB1_SET, + SOUND_GARAGE_BOMB2_SET, + SOUND_GARAGE_BOMB3_SET, + SOUND_40, + SOUND_41, + SOUND_GARAGE_VEHICLE_DECLINED, + SOUND_GARAGE_VEHICLE_ACCEPTED, + SOUND_GARAGE_DOOR_CLOSED, + SOUND_GARAGE_DOOR_OPENED, + SOUND_CRANE_PICKUP, + SOUND_PICKUP_WEAPON_BOUGHT, + SOUND_PICKUP_WEAPON, + SOUND_PICKUP_HEALTH, + SOUND_4A, + SOUND_4B, + SOUND_PICKUP_ADRENALINE, + SOUND_PICKUP_ARMOUR, + SOUND_PICKUP_BONUS, + SOUND_PICKUP_MONEY, + SOUND_PICKUP_HIDDEN_PACKAGE, + SOUND_PICKUP_PACMAN_PILL, + SOUND_PICKUP_PACMAN_PACKAGE, + SOUND_PICKUP_FLOAT_PACKAGE, + SOUND_BOMB_TIMED_ACTIVATED, + SOUND_55, + SOUND_BOMB_ONIGNITION_ACTIVATED, + SOUND_BOMB_TICK, + SOUND_RAMPAGE_START, + SOUND_RAMPAGE_ONGOING, + SOUND_RAMPAGE_PASSED, + SOUND_RAMPAGE_FAILED, + SOUND_RAMPAGE_KILL, + SOUND_RAMPAGE_CAR_BLOWN, + SOUND_EVIDENCE_PICKUP, + SOUND_UNLOAD_GOLD, + SOUND_PAGER, + SOUND_PED_DEATH, // 103 in VC + SOUND_PED_DAMAGE, // 104 in VC + SOUND_PED_HIT, // 105 in VC + SOUND_PED_LAND, // hopefully 106 in VC + SOUND_PED_BULLET_HIT, + SOUND_PED_BOMBER, + SOUND_PED_BURNING, // 108 in VC + SOUND_PED_ARREST_FBI, + SOUND_PED_ARREST_SWAT, + SOUND_PED_ARREST_COP, + SOUND_PED_HELI_PLAYER_FOUND, + SOUND_PED_HANDS_UP, + SOUND_PED_HANDS_COWER, + SOUND_PED_FLEE_SPRINT, // 120 in VC + SOUND_PED_CAR_JACKING, + SOUND_PED_MUGGING, + SOUND_PED_CAR_JACKED, + SOUND_PED_ROBBED, + SOUND_PED_TAXI_WAIT, // 137 in VC + SOUND_PED_ATTACK, + SOUND_PED_DEFEND, + SOUND_PED_PURSUIT_ARMY, + SOUND_PED_PURSUIT_FBI, + SOUND_PED_PURSUIT_SWAT, + SOUND_PED_PURSUIT_COP, + SOUND_PED_HEALING, + SOUND_PED_7B, + SOUND_PED_LEAVE_VEHICLE, + SOUND_PED_EVADE, // 142 in VC + SOUND_PED_FLEE_RUN, + SOUND_PED_CAR_COLLISION, // 144-145-146 in VC + SOUND_PED_SOLICIT, + SOUND_PED_EXTINGUISHING_FIRE, + SOUND_PED_WAIT_DOUBLEBACK, + SOUND_PED_CHAT_SEXY, + SOUND_PED_CHAT_EVENT, + SOUND_PED_CHAT, + SOUND_PED_BODYCAST_HIT, + SOUND_PED_TAXI_CALL, + SOUND_INJURED_PED_MALE_OUCH, + SOUND_INJURED_PED_FEMALE, + SOUND_INJURED_PED_MALE_PRISON, + SOUND_RACE_START_3, + SOUND_RACE_START_2, + SOUND_RACE_START_1, + SOUND_RACE_START_GO, + SOUND_SPLASH, + SOUND_WATER_FALL, + SOUND_SPLATTER, + SOUND_CAR_PED_COLLISION, + SOUND_CLOCK_TICK, + SOUND_PART_MISSION_COMPLETE, + SOUND_FRONTEND_MENU_STARTING, + SOUND_FRONTEND_MENU_COMPLETED, + SOUND_FRONTEND_MENU_DENIED, + SOUND_FRONTEND_MENU_SUCCESS, + SOUND_FRONTEND_EXIT, + SOUND_9A, + SOUND_9B, + SOUND_FRONTEND_AUDIO_TEST, + SOUND_FRONTEND_FAIL, + SOUND_FRONTEND_NO_RADIO, + SOUND_FRONTEND_RADIO_CHANGE, + SOUND_A0, + SOUND_AMMUNATION_WELCOME_1, + SOUND_AMMUNATION_WELCOME_2, + SOUND_AMMUNATION_WELCOME_3, + SOUND_LIGHTNING, + SOUND_A5, + SOUND_TOTAL_SOUNDS, + SOUND_NO_SOUND, }; -enum eScriptSounds : int16 { +enum eScriptSounds : uint16 { SCRIPT_SOUND_0 = 0, - SCRIPT_SOUND_1 = 1, - SCRIPT_SOUND_2 = 2, - SCRIPT_SOUND_3 = 3, - SCRIPT_SOUND_PARTY_1_LOOP_S = 4, - SCRIPT_SOUND_PARTY_1_LOOP_L = 5, - SCRIPT_SOUND_PARTY_2_LOOP_S = 6, - SCRIPT_SOUND_PARTY_2_LOOP_L = 7, - SCRIPT_SOUND_PARTY_3_LOOP_S = 8, - SCRIPT_SOUND_PARTY_3_LOOP_L = 9, - SCRIPT_SOUND_PARTY_4_LOOP_S = 10, - SCRIPT_SOUND_PARTY_4_LOOP_L = 11, - SCRIPT_SOUND_PARTY_5_LOOP_S = 12, - SCRIPT_SOUND_PARTY_5_LOOP_L = 13, - SCRIPT_SOUND_PARTY_6_LOOP_S = 14, - SCRIPT_SOUND_PARTY_6_LOOP_L = 15, - SCRIPT_SOUND_PARTY_7_LOOP_S = 16, - SCRIPT_SOUND_PARTY_7_LOOP_L = 17, - SCRIPT_SOUND_PARTY_8_LOOP_S = 18, - SCRIPT_SOUND_PARTY_8_LOOP_L = 19, - SCRIPT_SOUND_PARTY_9_LOOP_S = 20, - SCRIPT_SOUND_PARTY_9_LOOP_L = 21, - SCRIPT_SOUND_PARTY_10_LOOP_S = 22, - SCRIPT_SOUND_PARTY_10_LOOP_L = 23, - SCRIPT_SOUND_PARTY_11_LOOP_S = 24, - SCRIPT_SOUND_PARTY_11_LOOP_L = 25, - SCRIPT_SOUND_PARTY_12_LOOP_S = 26, - SCRIPT_SOUND_PARTY_12_LOOP_L = 27, - SCRIPT_SOUND_PARTY_13_LOOP_S = 28, - SCRIPT_SOUND_PARTY_13_LOOP_L = 29, - SCRIPT_SOUND_STRIP_CLUB_LOOP_1_S = 30, - SCRIPT_SOUND_STRIP_CLUB_LOOP_1_L = 31, - SCRIPT_SOUND_STRIP_CLUB_LOOP_2_S = 32, - SCRIPT_SOUND_STRIP_CLUB_LOOP_2_L = 33, - SCRIPT_SOUND_WORK_SHOP_LOOP_S = 34, - SCRIPT_SOUND_WORK_SHOP_LOOP_L = 35, - SCRIPT_SOUND_SAWMILL_LOOP_S = 36, - SCRIPT_SOUND_SAWMILL_LOOP_L = 37, - SCRIPT_SOUND_38 = 38, - SCRIPT_SOUND_39 = 39, - SCRIPT_SOUND_LAUNDERETTE_LOOP_S = 40, - SCRIPT_SOUND_LAUNDERETTE_LOOP_L = 41, - SCRIPT_SOUND_CHINATOWN_RESTAURANT_S = 42, - SCRIPT_SOUND_CHINATOWN_RESTAURANT_L = 43, - SCRIPT_SOUND_CIPRIANI_RESAURANT_S = 44, - SCRIPT_SOUND_CIPRIANI_RESAURANT_L = 45, - SCRIPT_SOUND_46_S = 46, - SCRIPT_SOUND_47_L = 47, - SCRIPT_SOUND_MARCO_BISTRO_S = 48, - SCRIPT_SOUND_MARCO_BISTRO_L = 49, - SCRIPT_SOUND_AIRPORT_LOOP_S = 50, - SCRIPT_SOUND_AIRPORT_LOOP_L = 51, - SCRIPT_SOUND_SHOP_LOOP_S = 52, - SCRIPT_SOUND_SHOP_LOOP_L = 53, - SCRIPT_SOUND_CINEMA_LOOP_S = 54, - SCRIPT_SOUND_CINEMA_LOOP_L = 55, - SCRIPT_SOUND_DOCKS_LOOP_S = 56, - SCRIPT_SOUND_DOCKS_LOOP_L = 57, - SCRIPT_SOUND_HOME_LOOP_S = 58, - SCRIPT_SOUND_HOME_LOOP_L = 59, - SCRIPT_SOUND_FRANKIE_PIANO = 60, - SCRIPT_SOUND_PARTY_1_LOOP = 61, - SCRIPT_SOUND_PORN_CINEMA_1_S = 62, - SCRIPT_SOUND_PORN_CINEMA_1_L = 63, - SCRIPT_SOUND_PORN_CINEMA_2_S = 64, - SCRIPT_SOUND_PORN_CINEMA_2_L = 65, - SCRIPT_SOUND_PORN_CINEMA_3_S = 66, - SCRIPT_SOUND_PORN_CINEMA_3_L = 67, - SCRIPT_SOUND_BANK_ALARM_LOOP_S = 68, - SCRIPT_SOUND_BANK_ALARM_LOOP_L = 69, - SCRIPT_SOUND_POLICE_BALL_LOOP_S = 70, - SCRIPT_SOUND_POLICE_BALL_LOOP_L = 71, - SCRIPT_SOUND_RAVE_LOOP_INDUSTRIAL_S = 72, - SCRIPT_SOUND_RAVE_LOOP_INDUSTRIAL_L = 73, - SCRIPT_SOUND_74 = 74, - SCRIPT_SOUND_75 = 75, - SCRIPT_SOUND_POLICE_CELL_BEATING_LOOP_S = 76, - SCRIPT_SOUND_POLICE_CELL_BEATING_LOOP_L = 77, - SCRIPT_SOUND_INJURED_PED_MALE_OUCH_S = 78, - SCRIPT_SOUND_INJURED_PED_MALE_OUCH_L = 79, - SCRIPT_SOUND_INJURED_PED_FEMALE_OUCH_S = 80, - SCRIPT_SOUND_INJURED_PED_FEMALE_OUCH_L = 81, - SCRIPT_SOUND_EVIDENCE_PICKUP = 82, - SCRIPT_SOUND_UNLOAD_GOLD = 83, - SCRIPT_SOUND_RAVE_1_LOOP_S = 84, - SCRIPT_SOUND_RAVE_1_LOOP_L = 85, - SCRIPT_SOUND_RAVE_2_LOOP_S = 86, - SCRIPT_SOUND_RAVE_2_LOOP_L = 87, - SCRIPT_SOUND_RAVE_3_LOOP_S = 88, - SCRIPT_SOUND_RAVE_3_LOOP_L = 89, - SCRIPT_SOUND_MISTY_SEX_S = 90, - SCRIPT_SOUND_MISTY_SEX_L = 91, - SCRIPT_SOUND_GATE_START_CLUNK = 92, - SCRIPT_SOUND_GATE_STOP_CLUNK = 93, - SCRIPT_SOUND_PART_MISSION_COMPLETE = 94, - SCRIPT_SOUND_CHUNKY_RUN_SHOUT = 95, - SCRIPT_SOUND_SECURITY_GUARD_AWAY_SHOUT = 96, - SCRIPT_SOUND_RACE_START_3 = 97, - SCRIPT_SOUND_RACE_START_2 = 98, - SCRIPT_SOUND_RACE_START_1 = 99, - SCRIPT_SOUND_RACE_START_GO = 100, - SCRIPT_SOUND_SWAT_PED_SHOUT = 101, - SCRIPT_SOUND_PRETEND_FIRE_LOOP = 102, - SCRIPT_SOUND_AMMUNATION_CHAT_1 = 103, - SCRIPT_SOUND_AMMUNATION_CHAT_2 = 104, - SCRIPT_SOUND_AMMUNATION_CHAT_3 = 105, - SCRIPT_SOUND_BULLET_HIT_GROUND_1 = 106, - SCRIPT_SOUND_BULLET_HIT_GROUND_2 = 107, - SCRIPT_SOUND_BULLET_HIT_GROUND_3 = 108, - SCRIPT_SOUND_BULLET_HIT_WATER = 109, //no sound - SCRIPT_SOUND_110 = 110, - SCRIPT_SOUND_111 = 111, - SCRIPT_SOUND_PAYPHONE_RINGING = 112, - SCRIPT_SOUND_113 = 113, - SCRIPT_SOUND_GLASS_BREAK_L = 114, - SCRIPT_SOUND_GLASS_BREAK_S = 115, - SCRIPT_SOUND_GLASS_CRACK = 116, - SCRIPT_SOUND_GLASS_LIGHT_BREAK = 117, - SCRIPT_SOUND_BOX_DESTROYED_1 = 118, - SCRIPT_SOUND_BOX_DESTROYED_2 = 119, - SCRIPT_SOUND_METAL_COLLISION = 120, - SCRIPT_SOUND_TIRE_COLLISION = 121, - SCRIPT_SOUND_GUNSHELL_DROP = 122, - SCRIPT_SOUND_GUNSHELL_DROP_SOFT = 123, + SCRIPT_SOUND_1, + SCRIPT_SOUND_2, + SCRIPT_SOUND_3, + SCRIPT_SOUND_PARTY_1_LOOP_S, + SCRIPT_SOUND_PARTY_1_LOOP_L, + SCRIPT_SOUND_PARTY_2_LOOP_S, + SCRIPT_SOUND_PARTY_2_LOOP_L, + SCRIPT_SOUND_PARTY_3_LOOP_S, + SCRIPT_SOUND_PARTY_3_LOOP_L, + SCRIPT_SOUND_PARTY_4_LOOP_S, + SCRIPT_SOUND_PARTY_4_LOOP_L, + SCRIPT_SOUND_PARTY_5_LOOP_S, + SCRIPT_SOUND_PARTY_5_LOOP_L, + SCRIPT_SOUND_PARTY_6_LOOP_S, + SCRIPT_SOUND_PARTY_6_LOOP_L, + SCRIPT_SOUND_PARTY_7_LOOP_S, + SCRIPT_SOUND_PARTY_7_LOOP_L, + SCRIPT_SOUND_PARTY_8_LOOP_S, + SCRIPT_SOUND_PARTY_8_LOOP_L, + SCRIPT_SOUND_PARTY_9_LOOP_S, + SCRIPT_SOUND_PARTY_9_LOOP_L, + SCRIPT_SOUND_PARTY_10_LOOP_S, + SCRIPT_SOUND_PARTY_10_LOOP_L, + SCRIPT_SOUND_PARTY_11_LOOP_S, + SCRIPT_SOUND_PARTY_11_LOOP_L, + SCRIPT_SOUND_PARTY_12_LOOP_S, + SCRIPT_SOUND_PARTY_12_LOOP_L, + SCRIPT_SOUND_PARTY_13_LOOP_S, + SCRIPT_SOUND_PARTY_13_LOOP_L, + SCRIPT_SOUND_STRIP_CLUB_LOOP_1_S, + SCRIPT_SOUND_STRIP_CLUB_LOOP_1_L, + SCRIPT_SOUND_STRIP_CLUB_LOOP_2_S, + SCRIPT_SOUND_STRIP_CLUB_LOOP_2_L, + SCRIPT_SOUND_WORK_SHOP_LOOP_S, + SCRIPT_SOUND_WORK_SHOP_LOOP_L, + SCRIPT_SOUND_SAWMILL_LOOP_S, + SCRIPT_SOUND_SAWMILL_LOOP_L, + SCRIPT_SOUND_38, + SCRIPT_SOUND_39, + SCRIPT_SOUND_LAUNDERETTE_LOOP_S, + SCRIPT_SOUND_LAUNDERETTE_LOOP_L, + SCRIPT_SOUND_CHINATOWN_RESTAURANT_S, + SCRIPT_SOUND_CHINATOWN_RESTAURANT_L, + SCRIPT_SOUND_CIPRIANI_RESAURANT_S, + SCRIPT_SOUND_CIPRIANI_RESAURANT_L, + SCRIPT_SOUND_46_S, + SCRIPT_SOUND_47_L, + SCRIPT_SOUND_MARCO_BISTRO_S, + SCRIPT_SOUND_MARCO_BISTRO_L, + SCRIPT_SOUND_AIRPORT_LOOP_S, + SCRIPT_SOUND_AIRPORT_LOOP_L, + SCRIPT_SOUND_SHOP_LOOP_S, + SCRIPT_SOUND_SHOP_LOOP_L, + SCRIPT_SOUND_CINEMA_LOOP_S, + SCRIPT_SOUND_CINEMA_LOOP_L, + SCRIPT_SOUND_DOCKS_LOOP_S, + SCRIPT_SOUND_DOCKS_LOOP_L, + SCRIPT_SOUND_HOME_LOOP_S, + SCRIPT_SOUND_HOME_LOOP_L, + SCRIPT_SOUND_FRANKIE_PIANO, + SCRIPT_SOUND_PARTY_1_LOOP, + SCRIPT_SOUND_PORN_CINEMA_1_S, + SCRIPT_SOUND_PORN_CINEMA_1_L, + SCRIPT_SOUND_PORN_CINEMA_2_S, + SCRIPT_SOUND_PORN_CINEMA_2_L, + SCRIPT_SOUND_PORN_CINEMA_3_S, + SCRIPT_SOUND_PORN_CINEMA_3_L, + SCRIPT_SOUND_BANK_ALARM_LOOP_S, + SCRIPT_SOUND_BANK_ALARM_LOOP_L, + SCRIPT_SOUND_POLICE_BALL_LOOP_S, + SCRIPT_SOUND_POLICE_BALL_LOOP_L, + SCRIPT_SOUND_RAVE_LOOP_INDUSTRIAL_S, + SCRIPT_SOUND_RAVE_LOOP_INDUSTRIAL_L, + SCRIPT_SOUND_74, + SCRIPT_SOUND_75, + SCRIPT_SOUND_POLICE_CELL_BEATING_LOOP_S, + SCRIPT_SOUND_POLICE_CELL_BEATING_LOOP_L, + SCRIPT_SOUND_INJURED_PED_MALE_OUCH_S, + SCRIPT_SOUND_INJURED_PED_MALE_OUCH_L, + SCRIPT_SOUND_INJURED_PED_FEMALE_OUCH_S, + SCRIPT_SOUND_INJURED_PED_FEMALE_OUCH_L, + SCRIPT_SOUND_EVIDENCE_PICKUP, + SCRIPT_SOUND_UNLOAD_GOLD, + SCRIPT_SOUND_RAVE_1_LOOP_S, + SCRIPT_SOUND_RAVE_1_LOOP_L, + SCRIPT_SOUND_RAVE_2_LOOP_S, + SCRIPT_SOUND_RAVE_2_LOOP_L, + SCRIPT_SOUND_RAVE_3_LOOP_S, + SCRIPT_SOUND_RAVE_3_LOOP_L, + SCRIPT_SOUND_MISTY_SEX_S, + SCRIPT_SOUND_MISTY_SEX_L, + SCRIPT_SOUND_GATE_START_CLUNK, + SCRIPT_SOUND_GATE_STOP_CLUNK, + SCRIPT_SOUND_PART_MISSION_COMPLETE, + SCRIPT_SOUND_CHUNKY_RUN_SHOUT, + SCRIPT_SOUND_SECURITY_GUARD_AWAY_SHOUT, + SCRIPT_SOUND_RACE_START_3, + SCRIPT_SOUND_RACE_START_2, + SCRIPT_SOUND_RACE_START_1, + SCRIPT_SOUND_RACE_START_GO, + SCRIPT_SOUND_SWAT_PED_SHOUT, + SCRIPT_SOUND_PRETEND_FIRE_LOOP, + SCRIPT_SOUND_AMMUNATION_CHAT_1, + SCRIPT_SOUND_AMMUNATION_CHAT_2, + SCRIPT_SOUND_AMMUNATION_CHAT_3, + SCRIPT_SOUND_BULLET_HIT_GROUND_1, + SCRIPT_SOUND_BULLET_HIT_GROUND_2, + SCRIPT_SOUND_BULLET_HIT_GROUND_3, + SCRIPT_SOUND_BULLET_HIT_WATER, // no sound + SCRIPT_SOUND_110, + SCRIPT_SOUND_111, + SCRIPT_SOUND_PAYPHONE_RINGING, + SCRIPT_SOUND_113, + SCRIPT_SOUND_GLASS_BREAK_L, + SCRIPT_SOUND_GLASS_BREAK_S, + SCRIPT_SOUND_GLASS_CRACK, + SCRIPT_SOUND_GLASS_LIGHT_BREAK, + SCRIPT_SOUND_BOX_DESTROYED_1, + SCRIPT_SOUND_BOX_DESTROYED_2, + SCRIPT_SOUND_METAL_COLLISION, + SCRIPT_SOUND_TIRE_COLLISION, + SCRIPT_SOUND_GUNSHELL_DROP, + SCRIPT_SOUND_GUNSHELL_DROP_SOFT, + SCRIPT_SOUND_TOTAL, + SCRIPT_SOUND_INVALID, }; diff --git a/src/control/CarAI.cpp b/src/control/CarAI.cpp index 0f80954b..121518f4 100644 --- a/src/control/CarAI.cpp +++ b/src/control/CarAI.cpp @@ -22,19 +22,18 @@ #define DISTANCE_TO_SWITCH_DISTANCE_GOTO 20.0f -//--MIAMI: done +//--MIAMI: file done + float CCarAI::FindSwitchDistanceClose(CVehicle* pVehicle) { return pVehicle->AutoPilot.m_nSwitchDistance; } -//--MIAMI: done float CCarAI::FindSwitchDistanceFarNormalVehicle(CVehicle* pVehicle) { return FindSwitchDistanceClose(pVehicle) + 5.0f; } -//--MIAMI: done float CCarAI::FindSwitchDistanceFar(CVehicle* pVehicle) { if (pVehicle->bIsLawEnforcer) @@ -42,7 +41,6 @@ float CCarAI::FindSwitchDistanceFar(CVehicle* pVehicle) return FindSwitchDistanceFarNormalVehicle(pVehicle); } -//--MIAMI: done void CCarAI::BackToCruisingIfNoWantedLevel(CVehicle* pVehicle) { if (FindPlayerPed()->m_pWanted->m_bIgnoredByEveryone || pVehicle->bIsLawEnforcer && @@ -56,7 +54,6 @@ void CCarAI::BackToCruisingIfNoWantedLevel(CVehicle* pVehicle) } } -//--MIAMI: done void CCarAI::UpdateCarAI(CVehicle* pVehicle) { if (pVehicle->bIsLawEnforcer){ @@ -350,6 +347,7 @@ void CCarAI::UpdateCarAI(CVehicle* pVehicle) if (!FindPlayerVehicle() || DotProduct2D(CVector2D(diff.x / distance, diff.y / distance), FindPlayerSpeed()) > 0.05f) pVehicle->AutoPilot.m_nCarMission = MISSION_BLOCKPLAYER_CLOSE; BackToCruisingIfNoWantedLevel(pVehicle); + break; } default: if (pVehicle->bIsLawEnforcer && FindPlayerPed()->m_pWanted->m_nWantedLevel > 0 && !CCullZones::NoPolice()){ @@ -358,7 +356,7 @@ void CCarAI::UpdateCarAI(CVehicle* pVehicle) pVehicle->AutoPilot.m_nCruiseSpeed = FindPoliceCarSpeedForWantedLevel(pVehicle); pVehicle->SetStatus(STATUS_PHYSICS); pVehicle->AutoPilot.m_nCarMission = - pVehicle->GetVehicleAppearance() == VEHICLE_BOAT ? FindPoliceBoatMissionForWantedLevel() : FindPoliceCarMissionForWantedLevel(); + pVehicle->GetVehicleAppearance() == VEHICLE_APPEARANCE_BOAT ? FindPoliceBoatMissionForWantedLevel() : FindPoliceCarMissionForWantedLevel(); pVehicle->AutoPilot.m_nTempAction = TEMPACT_NONE; pVehicle->AutoPilot.m_nDrivingStyle = DRIVINGSTYLE_AVOID_CARS; }else if (pVehicle->AutoPilot.m_nCarMission == MISSION_CRUISE){ @@ -432,7 +430,7 @@ void CCarAI::UpdateCarAI(CVehicle* pVehicle) if (pVehicle->bIsLawEnforcer) { if (pVehicle->AutoPilot.m_nCarMission == MISSION_RAMPLAYER_FARAWAY || pVehicle->AutoPilot.m_nCarMission == MISSION_RAMPLAYER_CLOSE) { - if (FindPlayerVehicle() && FindPlayerVehicle()->GetVehicleAppearance() == VEHICLE_BIKE) + if (FindPlayerVehicle() && FindPlayerVehicle()->GetVehicleAppearance() == VEHICLE_APPEARANCE_BIKE) pVehicle->AutoPilot.m_nCarMission = MISSION_BLOCKPLAYER_FARAWAY; } } @@ -489,16 +487,16 @@ void CCarAI::UpdateCarAI(CVehicle* pVehicle) if (pVehicle->bIsLawEnforcer && FindPlayerPed()->m_pWanted->m_nWantedLevel > 0) { if (!FindPlayerVehicle() || - FindPlayerVehicle()->GetVehicleAppearance() == VEHICLE_CAR || - FindPlayerVehicle()->GetVehicleAppearance() == VEHICLE_BIKE) { - if (pVehicle->GetVehicleAppearance() == VEHICLE_BOAT) { + FindPlayerVehicle()->GetVehicleAppearance() == VEHICLE_APPEARANCE_CAR || + FindPlayerVehicle()->GetVehicleAppearance() == VEHICLE_APPEARANCE_BIKE) { + if (pVehicle->GetVehicleAppearance() == VEHICLE_APPEARANCE_BOAT) { pVehicle->AutoPilot.m_nTempAction = TEMPACT_WAIT; pVehicle->AutoPilot.m_nTimeTempAction = CTimer::GetTimeInMilliseconds() + 1000; } } - else if (FindPlayerVehicle()->GetVehicleAppearance() == VEHICLE_BOAT) { - if (pVehicle->GetVehicleAppearance() == VEHICLE_CAR || - pVehicle->GetVehicleAppearance() == VEHICLE_BIKE) { + else if (FindPlayerVehicle()->GetVehicleAppearance() == VEHICLE_APPEARANCE_BOAT) { + if (pVehicle->GetVehicleAppearance() == VEHICLE_APPEARANCE_CAR || + pVehicle->GetVehicleAppearance() == VEHICLE_APPEARANCE_BIKE) { pVehicle->AutoPilot.m_nTempAction = TEMPACT_WAIT; pVehicle->AutoPilot.m_nTimeTempAction = CTimer::GetTimeInMilliseconds() + 1000; } @@ -506,13 +504,11 @@ void CCarAI::UpdateCarAI(CVehicle* pVehicle) } } -//--MIAMI: done void CCarAI::CarHasReasonToStop(CVehicle* pVehicle) { pVehicle->AutoPilot.m_nAntiReverseTimer = CTimer::GetTimeInMilliseconds(); } -//--MIAMI: done float CCarAI::GetCarToGoToCoors(CVehicle* pVehicle, CVector* pTarget) { if (pVehicle->AutoPilot.m_nCarMission != MISSION_GOTOCOORDS && pVehicle->AutoPilot.m_nCarMission != MISSION_GOTOCOORDS_STRAIGHT){ @@ -530,7 +526,6 @@ float CCarAI::GetCarToGoToCoors(CVehicle* pVehicle, CVector* pTarget) return (pVehicle->GetPosition() - *pTarget).Magnitude2D(); } -//--MIAMI: done float CCarAI::GetCarToParkAtCoors(CVehicle* pVehicle, CVector* pTarget) { GetCarToGoToCoors(pVehicle, pTarget); @@ -539,7 +534,6 @@ float CCarAI::GetCarToParkAtCoors(CVehicle* pVehicle, CVector* pTarget) return (pVehicle->GetPosition() - *pTarget).Magnitude2D(); } -//--MIAMI: TODO: MI_VICECHEE void CCarAI::AddPoliceCarOccupants(CVehicle* pVehicle) { if (pVehicle->bOccupantsHaveBeenGenerated) @@ -576,21 +570,18 @@ void CCarAI::AddPoliceCarOccupants(CVehicle* pVehicle) } } -//--MIAMI: done void CCarAI::AddAmbulanceOccupants(CVehicle* pVehicle) { pVehicle->SetUpDriver(); pVehicle->SetupPassenger(1); } -//--MIAMI: done void CCarAI::AddFiretruckOccupants(CVehicle* pVehicle) { pVehicle->SetUpDriver(); pVehicle->SetupPassenger(0); } -//--MIAMI: done void CCarAI::TellOccupantsToLeaveCar(CVehicle* pVehicle) { if (pVehicle->pDriver){ @@ -608,7 +599,6 @@ void CCarAI::TellOccupantsToLeaveCar(CVehicle* pVehicle) } } -//--MIAMI: done void CCarAI::TellOccupantsToFleeCar(CVehicle* pVehicle) { if (pVehicle->pDriver && !pVehicle->pDriver->IsPlayer()) { @@ -626,7 +616,6 @@ void CCarAI::TellOccupantsToFleeCar(CVehicle* pVehicle) } } -//--MIAMI: done void CCarAI::TellCarToRamOtherCar(CVehicle* pVehicle, CVehicle* pTarget) { pVehicle->AutoPilot.m_pTargetCar = pTarget; @@ -636,7 +625,6 @@ void CCarAI::TellCarToRamOtherCar(CVehicle* pVehicle, CVehicle* pTarget) pVehicle->AutoPilot.m_nCruiseSpeed = Max(6, pVehicle->AutoPilot.m_nCruiseSpeed); } -//--MIAMI: done void CCarAI::TellCarToBlockOtherCar(CVehicle* pVehicle, CVehicle* pTarget) { pVehicle->AutoPilot.m_pTargetCar = pTarget; @@ -646,7 +634,6 @@ void CCarAI::TellCarToBlockOtherCar(CVehicle* pVehicle, CVehicle* pTarget) pVehicle->AutoPilot.m_nCruiseSpeed = Max(6, pVehicle->AutoPilot.m_nCruiseSpeed); } -//--MIAMI: done eCarMission CCarAI::FindPoliceCarMissionForWantedLevel() { switch (CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_pWanted->m_nWantedLevel){ @@ -661,7 +648,6 @@ eCarMission CCarAI::FindPoliceCarMissionForWantedLevel() } } -//--MIAMI: done eCarMission CCarAI::FindPoliceBoatMissionForWantedLevel() { switch (CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_pWanted->m_nWantedLevel) { @@ -676,7 +662,6 @@ eCarMission CCarAI::FindPoliceBoatMissionForWantedLevel() } } -//--MIAMI: done int32 CCarAI::FindPoliceCarSpeedForWantedLevel(CVehicle* pVehicle) { switch (CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_pWanted->m_nWantedLevel) { @@ -691,7 +676,6 @@ int32 CCarAI::FindPoliceCarSpeedForWantedLevel(CVehicle* pVehicle) } } -//--MIAMI: done void CCarAI::MellowOutChaseSpeed(CVehicle* pVehicle) { if (CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_pWanted->m_nWantedLevel == 1){ @@ -736,7 +720,6 @@ void CCarAI::MellowOutChaseSpeed(CVehicle* pVehicle) } } -//--MIAMI: done void CCarAI::MellowOutChaseSpeedBoat(CVehicle* pVehicle) { switch (CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_pWanted->m_nWantedLevel) { @@ -750,7 +733,6 @@ void CCarAI::MellowOutChaseSpeedBoat(CVehicle* pVehicle) } } -//--MIAMI: done void CCarAI::MakeWayForCarWithSiren(CVehicle *pVehicle) { float flatSpeed = pVehicle->GetMoveSpeed().Magnitude2D(); diff --git a/src/control/CarCtrl.cpp b/src/control/CarCtrl.cpp index c1d89884..ebaa5f29 100644 --- a/src/control/CarCtrl.cpp +++ b/src/control/CarCtrl.cpp @@ -105,6 +105,8 @@ int32 CCarCtrl::LoadedCarsArray[TOTAL_CUSTOM_CLASSES][MAX_CAR_MODELS_IN_ARRAY]; CVehicle* apCarsToKeep[MAX_CARS_TO_KEEP]; uint32 aCarsToKeepTime[MAX_CARS_TO_KEEP]; +//--MIAMI: done except heli/plane functions + void CCarCtrl::GenerateRandomCars() { @@ -500,10 +502,6 @@ CCarCtrl::GenerateOneRandomCar() directionNextLinkY = pNextLink->GetDirY() * pVehicle->AutoPilot.m_nNextDirection; } #else - float currentPathLinkForwardX = pVehicle->AutoPilot.m_nCurrentDirection * ThePaths.m_carPathLinks[pVehicle->AutoPilot.m_nCurrentPathNodeInfo].GetDirX(); - float currentPathLinkForwardY = pVehicle->AutoPilot.m_nCurrentDirection * ThePaths.m_carPathLinks[pVehicle->AutoPilot.m_nCurrentPathNodeInfo].GetDirY(); - float nextPathLinkForwardX = pVehicle->AutoPilot.m_nNextDirection * ThePaths.m_carPathLinks[pVehicle->AutoPilot.m_nNextPathNodeInfo].GetDirX(); - float nextPathLinkForwardY = pVehicle->AutoPilot.m_nNextDirection * ThePaths.m_carPathLinks[pVehicle->AutoPilot.m_nNextPathNodeInfo].GetDirY(); CCarPathLink* pCurrentLink = &ThePaths.m_carPathLinks[pVehicle->AutoPilot.m_nCurrentPathNodeInfo]; CCarPathLink* pNextLink = &ThePaths.m_carPathLinks[pVehicle->AutoPilot.m_nNextPathNodeInfo]; @@ -655,10 +653,10 @@ CCarCtrl::GenerateOneRandomCar() } int nMadDrivers; switch (pVehicle->GetVehicleAppearance()) { - case VEHICLE_BIKE: + case VEHICLE_APPEARANCE_BIKE: nMadDrivers = 30; break; - case VEHICLE_BOAT: + case VEHICLE_APPEARANCE_BOAT: nMadDrivers = 40; break; default: @@ -889,8 +887,7 @@ CCarCtrl::ChoosePoliceCarModel(void) int32 CCarCtrl::ChooseGangCarModel(int32 gang) { - if (CStreaming::HasModelLoaded(MI_GANG01 + 2 * gang) && - CStreaming::HasModelLoaded(MI_GANG01+1 + 2 * gang)) + if (CGangs::HaveGangModelsLoaded(gang)) return CGangs::GetGangVehicleModel(gang); return -1; } @@ -912,7 +909,7 @@ CCarCtrl::RemoveDistantCars() PossiblyRemoveVehicle(pVehicle); if (pVehicle->bCreateRoadBlockPeds){ if ((pVehicle->GetPosition() - FindPlayerCentreOfWorld(CWorld::PlayerInFocus)).Magnitude2D() < DISTANCE_TO_SPAWN_ROADBLOCK_PEDS) { - CRoadBlocks::GenerateRoadBlockCopsForCar(pVehicle, pVehicle->m_nRoadblockType, pVehicle->m_nRoadblockNode); + CRoadBlocks::GenerateRoadBlockCopsForCar(pVehicle, pVehicle->m_nRoadblockType); pVehicle->bCreateRoadBlockPeds = false; } } @@ -972,7 +969,8 @@ CCarCtrl::PossiblyRemoveVehicle(CVehicle* pVehicle) pVehicle->GetModelIndex() == MI_AMBULAN || pVehicle->GetModelIndex() == MI_FIRETRUCK || pVehicle->bIsLawEnforcer || - pVehicle->bIsCarParkVehicle + pVehicle->bIsCarParkVehicle || + CTimer::GetTimeInMilliseconds() < pVehicle->m_nSetPieceExtendedRangeTime ){ threshold = ONSCREEN_DESPAWN_RANGE * TheCamera.GenerationDistMultiplier; } @@ -1898,12 +1896,18 @@ void CCarCtrl::PickNextNodeRandomly(CVehicle* pVehicle) pVehicle->AutoPilot.m_nNextLane = 0; #ifdef FIX_BUGS CVector positionOnCurrentLinkIncludingLane( - pCurLink->GetX() + ((pVehicle->AutoPilot.m_nCurrentLane + pCurLink->OneWayLaneOffset()) * LANE_WIDTH) * currentPathLinkForwardY, - pCurLink->GetY() - ((pVehicle->AutoPilot.m_nCurrentLane + pCurLink->OneWayLaneOffset()) * LANE_WIDTH) * currentPathLinkForwardX, + pCurLink->GetX() + ((pVehicle->AutoPilot.m_nCurrentLane + pCurLink->OneWayLaneOffset()) * LANE_WIDTH) +#ifdef FIX_BUGS + * currentPathLinkForwardY +#endif + ,pCurLink->GetY() - ((pVehicle->AutoPilot.m_nCurrentLane + pCurLink->OneWayLaneOffset()) * LANE_WIDTH) * currentPathLinkForwardX, 0.0f); CVector positionOnNextLinkIncludingLane( - pNextLink->GetX() + ((pVehicle->AutoPilot.m_nNextLane + pNextLink->OneWayLaneOffset()) * LANE_WIDTH) * nextPathLinkForwardY, - pNextLink->GetY() - ((pVehicle->AutoPilot.m_nNextLane + pNextLink->OneWayLaneOffset()) * LANE_WIDTH) * nextPathLinkForwardX, + pNextLink->GetX() + ((pVehicle->AutoPilot.m_nNextLane + pNextLink->OneWayLaneOffset()) * LANE_WIDTH) +#ifdef FIX_BUGS + * nextPathLinkForwardY +#endif + ,pNextLink->GetY() - ((pVehicle->AutoPilot.m_nNextLane + pNextLink->OneWayLaneOffset()) * LANE_WIDTH) * nextPathLinkForwardX, 0.0f); #else CVector positionOnCurrentLinkIncludingLane( @@ -2516,7 +2520,7 @@ void CCarCtrl::SteerAICarWithPhysics_OnlyMission(CVehicle* pVehicle, float* pSwe pSwerve, pAccel, pBrake, pHandbrake); return; case MISSION_BLOCKPLAYER_FORWARDANDBACK: - //SteerAICarBlockingPlayerForwardAndBack(pVehicle, pSwerve, pAccel, pBrake, pHandbrake); + SteerAICarBlockingPlayerForwardAndBack(pVehicle, pSwerve, pAccel, pBrake, pHandbrake); return; default: assert(0); @@ -2524,6 +2528,45 @@ void CCarCtrl::SteerAICarWithPhysics_OnlyMission(CVehicle* pVehicle, float* pSwe } } +void CCarCtrl::SteerAICarBlockingPlayerForwardAndBack(CVehicle* pVehicle, float* pSwerve, float* pAccel, float* pBrake, bool* pHandbrake) +{ + *pSwerve = 0.0f; + *pHandbrake = false; + CVector player = FindPlayerSpeed() + 0.1f * FindPlayerEntity()->GetForward(); + player.z = 0.0f; + CVector right(pVehicle->GetRight().x, pVehicle->GetRight().y, 0.0f); + right.Normalise(); + CVector forward(pVehicle->GetForward().x, pVehicle->GetForward().y, 0.0f); + forward.Normalise(); + float dpPlayerAndRight = DotProduct(player, right); + if (dpPlayerAndRight == 0.0f) + dpPlayerAndRight = 0.01f; + float dpDiffAndRight = -DotProduct((FindPlayerCoors() - pVehicle->GetPosition()), right) / dpPlayerAndRight; + if (dpDiffAndRight < 0.0f) { + *pAccel = 0.0f; + *pBrake = 0.0f; + return; + } + float dpSpeedAndForward = DotProduct(pVehicle->GetMoveSpeed(), forward); + float dpPlayerAndForward = DotProduct(player, forward); + float dpDiffAndForward = DotProduct((FindPlayerCoors() - pVehicle->GetPosition()), forward); + float multiplier = dpPlayerAndForward * dpDiffAndRight + dpDiffAndForward - dpSpeedAndForward * dpDiffAndRight; + if (multiplier > 0) { + *pAccel = Min(1.0f, 0.1f * multiplier); + *pBrake = 0.0f; + } + else if (dpSpeedAndForward > 0) { + *pAccel = 0.0f; + *pBrake = Min(1.0f, -0.1f * multiplier); + if (*pBrake > 0.95f) + *pHandbrake = true; + } + else { + *pAccel = Max(-1.0f, 0.1f * multiplier); + *pBrake = 0.0f; + } +} + void CCarCtrl::SteerAIBoatWithPhysicsHeadingForTarget(CVehicle* pVehicle, float targetX, float targetY, float* pSwerve, float* pAccel, float* pBrake) { CVector2D forward = pVehicle->GetForward(); @@ -2996,7 +3039,9 @@ void CCarCtrl::FindLinksToGoWithTheseNodes(CVehicle* pVehicle) CPathNode* pNode = &ThePaths.m_pathNodes[node]; if (node == pVehicle->AutoPilot.m_nNextRouteNode) continue; - float dist = CCollision::DistToLine(&pCurNode->GetPosition(), &pNode->GetPosition(), &pVehicle->GetPosition()); + CVector vCurPos = pCurNode->GetPosition(); + CVector vNextPos = pNode->GetPosition(); + float dist = CCollision::DistToLine(&vCurPos, &vNextPos, &pVehicle->GetPosition()); if (dist < md) { md = dist; closestLink = curLink; diff --git a/src/control/CarCtrl.h b/src/control/CarCtrl.h index 8138266f..ed63a0e2 100644 --- a/src/control/CarCtrl.h +++ b/src/control/CarCtrl.h @@ -9,6 +9,7 @@ #define TIME_COPS_WAIT_TO_EXIT_AFTER_STOPPING 2500 class CZoneInfo; +class CAutomobile; enum{ MAX_CARS_TO_KEEP = 2, @@ -39,19 +40,19 @@ public: WORKERBOAT, COPS, - MAFIA, - TRIAD, - DIABLO, - YAKUZA, - YARDIE, - COLOMB, - NINES, - GANG8, + CUBAN, + HAITIAN, + STREET, + DIAZ, + BIKER, + SECURITY, + PLAYER, + GOLFERS, GANG9, COPS_BOAT, FIRST_CAR_RATING = NORMAL, FIRST_BOAT_RATING = LEISUREBOAT, - FIRST_GANG_CAR_RATING = MAFIA, + FIRST_GANG_CAR_RATING = CUBAN, NUM_CAR_CLASSES = MOTORBIKE - FIRST_CAR_RATING + 1, NUM_BOAT_CLASSES = WORKERBOAT - FIRST_BOAT_RATING + 1, NUM_GANG_CAR_CLASSES = GANG9 - FIRST_GANG_CAR_RATING + 1, diff --git a/src/control/Curves.cpp b/src/control/Curves.cpp index 31a2767a..29471608 100644 --- a/src/control/Curves.cpp +++ b/src/control/Curves.cpp @@ -2,6 +2,8 @@ #include "Curves.h" +//--MIAMI: file done + float CCurves::CalcSpeedScaleFactor(CVector* pPoint1, CVector* pPoint2, float dir1X, float dir1Y, float dir2X, float dir2Y) { CVector2D dir1(dir1X, dir1Y); diff --git a/src/control/Garages.cpp b/src/control/Garages.cpp index 82003561..64ebddfe 100644 --- a/src/control/Garages.cpp +++ b/src/control/Garages.cpp @@ -960,7 +960,7 @@ void CGarage::Update() if (m_pDoor1) { if (((CVector2D)FindPlayerVehicle()->GetPosition() - (CVector2D)m_pDoor1->GetPosition()).MagnitudeSqr() < SQR(DISTANCE_TO_SHOW_HIDEOUT_MESSAGE) && CTimer::GetTimeInMilliseconds() - CGarages::LastTimeHelpMessage > TIME_BETWEEN_HIDEOUT_MESSAGES) { - if (FindPlayerVehicle()->GetVehicleAppearance() != VEHICLE_HELI && FindPlayerVehicle()->GetVehicleAppearance() != VEHICLE_PLANE) { + if (FindPlayerVehicle()->GetVehicleAppearance() != VEHICLE_APPEARANCE_HELI && FindPlayerVehicle()->GetVehicleAppearance() != VEHICLE_APPEARANCE_PLANE) { CHud::SetHelpMessage(TheText.Get("GA_21"), false); // You cannot store any more cars in this garage. CGarages::LastTimeHelpMessage = CTimer::GetTimeInMilliseconds(); } @@ -1781,7 +1781,14 @@ CVehicle* CStoredCar::RestoreCar() CStreaming::RequestModel(m_nModelIndex, STREAMFLAGS_DEPENDENCY); if (!CStreaming::HasModelLoaded(m_nModelIndex)) return nil; - CVehicleModelInfo::SetComponentsToUse(m_nVariationA, m_nVariationB); +#ifdef FIX_BUGS + CVehicleModelInfo* pModelInfo = (CVehicleModelInfo*)CModelInfo::GetModelInfo(m_nModelIndex); + assert(pModelInfo); + if (pModelInfo->m_numComps != 0) +#endif + { + CVehicleModelInfo::SetComponentsToUse(m_nVariationA, m_nVariationB); + } CVehicle* pVehicle; if (CModelInfo::IsBoatModel(m_nModelIndex)) pVehicle = new CBoat(m_nModelIndex, RANDOM_VEHICLE); @@ -2119,12 +2126,8 @@ void CGarages::SetAllDoorsBackToOriginalHeight() // TODO(MIAMI) void CGarages::Save(uint8 * buf, uint32 * size) { -#ifdef FIX_GARAGE_SIZE - INITSAVEBUF - *size = (6 * sizeof(uint32) + TOTAL_COLLECTCARS_GARAGES * sizeof(*CarTypesCollected) + sizeof(uint32) + 3 * NUM_GARAGE_STORED_CARS * sizeof(CStoredCar) + NUM_GARAGES * sizeof(CGarage)); -#else - * size = 5484; -#endif +INITSAVEBUF + *size = (6 * sizeof(uint32) + TOTAL_COLLECTCARS_GARAGES * sizeof(*CarTypesCollected) + sizeof(uint32) + TOTAL_HIDEOUT_GARAGES * NUM_GARAGE_STORED_CARS * sizeof(CStoredCar) + NUM_GARAGES * sizeof(CGarage)); CloseHideOutGaragesBeforeSave(); WriteSaveBuf(buf, NumGarages); WriteSaveBuf(buf, (uint32)BombsAreFree); @@ -2142,9 +2145,7 @@ void CGarages::Save(uint8 * buf, uint32 * size) } for (int i = 0; i < NUM_GARAGES; i++) WriteSaveBuf(buf, aGarages[i]); -#ifdef FIX_GARAGE_SIZE - VALIDATESAVEBUF(*size); -#endif +VALIDATESAVEBUF(*size); } const CStoredCar &CStoredCar::operator=(const CStoredCar & other) @@ -2169,12 +2170,8 @@ const CStoredCar &CStoredCar::operator=(const CStoredCar & other) //TODO(MIAMI) void CGarages::Load(uint8* buf, uint32 size) { -#ifdef FIX_GARAGE_SIZE - INITSAVEBUF - assert(size == (6 * sizeof(uint32) + TOTAL_COLLECTCARS_GARAGES * sizeof(*CarTypesCollected) + sizeof(uint32) + 3 * NUM_GARAGE_STORED_CARS * sizeof(CStoredCar) + NUM_GARAGES * sizeof(CGarage)); -#else - assert(size == 5484); -#endif +INITSAVEBUF + assert(size == (6 * sizeof(uint32) + TOTAL_COLLECTCARS_GARAGES * sizeof(*CarTypesCollected) + sizeof(uint32) + TOTAL_HIDEOUT_GARAGES * NUM_GARAGE_STORED_CARS * sizeof(CStoredCar) + NUM_GARAGES * sizeof(CGarage))); CloseHideOutGaragesBeforeSave(); NumGarages = ReadSaveBuf(buf); BombsAreFree = ReadSaveBuf(buf); @@ -2203,9 +2200,7 @@ void CGarages::Load(uint8* buf, uint32 size) else aGarages[i].UpdateDoorsHeight(); } -#ifdef FIX_GARAGE_SIZE - VALIDATESAVEBUF(size); -#endif +VALIDATESAVEBUF(size); MessageEndTime = 0; bCamShouldBeOutisde = false; diff --git a/src/control/Garages.h b/src/control/Garages.h index c5bede2b..79905ede 100644 --- a/src/control/Garages.h +++ b/src/control/Garages.h @@ -294,7 +294,6 @@ private: case GARAGE_HIDEOUT_TEN: return 9; case GARAGE_HIDEOUT_ELEVEN: return 10; case GARAGE_HIDEOUT_TWELVE: return 11; - default: assert(0); } return -1; } diff --git a/src/control/OnscreenTimer.cpp b/src/control/OnscreenTimer.cpp index d128efeb..d94e993e 100644 --- a/src/control/OnscreenTimer.cpp +++ b/src/control/OnscreenTimer.cpp @@ -20,8 +20,9 @@ void COnscreenTimer::Init() { } m_sEntries[i].m_nType = COUNTER_DISPLAY_NUMBER; - m_sEntries[i].m_bTimerProcessed = 0; - m_sEntries[i].m_bCounterProcessed = 0; + m_sEntries[i].m_bTimerProcessed = false; + m_sEntries[i].m_bCounterProcessed = false; + m_sEntries[i].m_bTimerGoingDown = true; } } @@ -65,26 +66,21 @@ void COnscreenTimer::ClearClock(uint32 offset) { } } -void COnscreenTimer::AddCounter(uint32 offset, uint16 type, char* text) { - uint32 i = 0; - for(uint32 i = 0; i < NUMONSCREENTIMERENTRIES; i++) { - if(m_sEntries[i].m_nCounterOffset == 0) { - break; - } +void COnscreenTimer::AddCounter(uint32 offset, uint16 type, char* text, uint16 pos) { + + m_sEntries[pos].m_nCounterOffset = offset; + if (m_sEntries[pos].m_aCounterText[0] != '\0') return; - } - - m_sEntries[i].m_nCounterOffset = offset; if(text) { - strncpy(m_sEntries[i].m_aCounterText, text, 10); + strncpy(m_sEntries[pos].m_aCounterText, text, 10); } else { - m_sEntries[i].m_aCounterText[0] = 0; + m_sEntries[pos].m_aCounterText[0] = 0; } - m_sEntries[i].m_nType = type; + m_sEntries[pos].m_nType = type; } -void COnscreenTimer::AddClock(uint32 offset, char* text) { +void COnscreenTimer::AddClock(uint32 offset, char* text, bool bGoingDown) { uint32 i = 0; for(uint32 i = 0; i < NUMONSCREENTIMERENTRIES; i++) { if(m_sEntries[i].m_nTimerOffset == 0) { @@ -94,6 +90,7 @@ void COnscreenTimer::AddClock(uint32 offset, char* text) { } m_sEntries[i].m_nTimerOffset = offset; + m_sEntries[i].m_bTimerGoingDown = bGoingDown; if(text) { strncpy(m_sEntries[i].m_aTimerText, text, 10); } else { @@ -108,19 +105,24 @@ void COnscreenTimerEntry::Process() { int32* timerPtr = CTheScripts::GetPointerToScriptVariable(m_nTimerOffset); int32 oldTime = *timerPtr; - int32 newTime = oldTime - int32(CTimer::GetTimeStepInSeconds() * 1000); - if(newTime < 0) { - *timerPtr = 0; - m_bTimerProcessed = 0; - m_nTimerOffset = 0; - m_aTimerText[0] = 0; - } else { - *timerPtr = newTime; - int32 oldTimeSeconds = oldTime / 1000; - if(oldTimeSeconds < 12 && newTime / 1000 != oldTimeSeconds) { - DMAudio.PlayFrontEndSound(SOUND_CLOCK_TICK, newTime / 1000); + if (m_bTimerGoingDown) { + int32 newTime = oldTime - int32(CTimer::GetTimeStepInMilliseconds()); + if (newTime < 0) { + *timerPtr = 0; + m_bTimerProcessed = 0; + m_nTimerOffset = 0; + m_aTimerText[0] = 0; + } + else { + *timerPtr = newTime; + int32 oldTimeSeconds = oldTime / 1000; + if (oldTimeSeconds < 12 && newTime / 1000 != oldTimeSeconds) { + DMAudio.PlayFrontEndSound(SOUND_CLOCK_TICK, newTime / 1000); + } } } + else + *timerPtr = oldTime + int32(CTimer::GetTimeStepInMilliseconds()); } bool COnscreenTimerEntry::ProcessForDisplay() { diff --git a/src/control/OnscreenTimer.h b/src/control/OnscreenTimer.h index 3ef7764a..09473397 100644 --- a/src/control/OnscreenTimer.h +++ b/src/control/OnscreenTimer.h @@ -17,6 +17,7 @@ public: char m_bCounterBuffer[42]; char m_bTimerBuffer[42]; bool m_bTimerProcessed; + bool m_bTimerGoingDown; bool m_bCounterProcessed; void Process(); @@ -42,8 +43,8 @@ public: void ClearCounter(uint32 offset); void ClearClock(uint32 offset); - void AddCounter(uint32 offset, uint16 type, char* text); - void AddClock(uint32 offset, char* text); + void AddCounter(uint32 offset, uint16 type, char* text, uint16 pos); + void AddClock(uint32 offset, char* text, bool bGoingDown); }; VALIDATE_SIZE(COnscreenTimer, 0x78); diff --git a/src/control/Phones.cpp b/src/control/Phones.cpp index ee01b6c4..6fac3f9d 100644 --- a/src/control/Phones.cpp +++ b/src/control/Phones.cpp @@ -12,6 +12,7 @@ #include "AudioScriptObject.h" #include "RpAnimBlend.h" #include "AnimBlendAssociation.h" +#include "soundlist.h" #ifdef FIX_BUGS #include "Replay.h" #endif @@ -97,7 +98,7 @@ CPhoneInfo::Update(void) if (scratchTheCabinet) { m_aPhones[phoneId].m_pEntity->GetUp().z = (CGeneral::GetRandomNumber() % 1024) / 16000.0f + 1.0f; if (!phoneRings) - PlayOneShotScriptObject(_SCRSOUND_PHONE_RING, m_aPhones[phoneId].m_pEntity->GetPosition()); + PlayOneShotScriptObject(SCRIPT_SOUND_PAYPHONE_RINGING, m_aPhones[phoneId].m_pEntity->GetPosition()); } else { m_aPhones[phoneId].m_pEntity->GetUp().z = 1.0f; } @@ -136,7 +137,7 @@ CPhoneInfo::Update(void) if (scratchTheCabinet) { m_aPhones[phoneId].m_pEntity->GetUp().z = (CGeneral::GetRandomNumber() % 1024) / 16000.0f + 1.0f; if (!phoneRings) - PlayOneShotScriptObject(_SCRSOUND_PHONE_RING, m_aPhones[phoneId].m_pEntity->GetPosition()); + PlayOneShotScriptObject(SCRIPT_SOUND_PAYPHONE_RINGING, m_aPhones[phoneId].m_pEntity->GetPosition()); } else { m_aPhones[phoneId].m_pEntity->GetUp().z = 1.0f; } diff --git a/src/control/Pickups.cpp b/src/control/Pickups.cpp index 330b5788..1d2d06f7 100644 --- a/src/control/Pickups.cpp +++ b/src/control/Pickups.cpp @@ -44,15 +44,35 @@ uint32 CPickups::StaticCamStartTime; tPickupMessage CPickups::aMessages[NUMPICKUPMESSAGES]; -// 20 ?! Some Miami leftover? (Originally at 0x5ED8D4) +// TODO(Miami) uint16 AmmoForWeapon[20] = { 0, 1, 45, 125, 25, 150, 300, 25, 5, 250, 5, 5, 0, 500, 0, 100, 0, 0, 0, 0 }; -uint16 AmmoForWeapon_OnStreet[20] = { 0, 1, 9, 25, 5, 30, 60, 5, 1, 50, 1, 1, 0, 200, 0, 100, 0, 0, 0, 0 }; + +// --MIAMI: Done +uint16 AmmoForWeapon_OnStreet[WEAPONTYPE_TOTALWEAPONS] = { + 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 4, 4, 4, 4, 34, + 12, 16, 14, 10, 100, 60, 60, 60, 60, 60, 20, 14, + 4, 150, 100, 500, 1, 400, 36, 0, +}; uint16 CostOfWeapon[20] = { 0, 10, 250, 800, 1500, 3000, 5000, 10000, 25000, 25000, 2000, 2000, 0, 50000, 0, 3000, 0, 0, 0, 0 }; -uint8 aWeaponReds[] = { 255, 0, 128, 255, 255, 0, 255, 0, 128, 128, 255, 255, 128, 0, 255, 0 }; -uint8 aWeaponGreens[] = { 0, 255, 128, 255, 0, 255, 128, 255, 0, 255, 255, 0, 255, 0, 255, 0 }; -uint8 aWeaponBlues[] = { 0, 0, 255, 0, 255, 255, 0, 128, 255, 0, 255, 0, 128, 255, 0, 0 }; -float aWeaponScale[] = { 1.0f, 2.0f, 1.5f, 1.0f, 1.0f, 1.5f, 1.0f, 2.0f, 1.0f, 2.0f, 2.5f, 1.0f, 1.0f, 1.0f, 1.0f }; +// TODO(Miami): Those are all placeholders!! +uint8 aWeaponReds[] = { 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, +255, 0, 128, 255, 255, 0, 255, 0, 128, 128, 255, +255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, +255, 128, 0, 255, 0 }; +uint8 aWeaponGreens[] = { 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, +0, 255, 128, 255, 0, 255, 128, 255, 0, 255, 255, +255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, +0, 255, 0, 255, 0 }; +uint8 aWeaponBlues[] = { 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, +0, 0, 255, 0, 255, 255, 0, 128, 255, 0, 255, +255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, +0, 128, 255, 0, 0 }; + +float aWeaponScale[] = { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, +2.0f, 1.5f, 1.0f, 1.0f, 1.5f, 1.0f, 2.0f, 1.0f, 2.0f, 2.5f, 1.0f, +1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, +1.0f, 1.0f, 1.0f, 1.0f }; void CPickup::RemoveKeepType() @@ -93,6 +113,7 @@ CPickup::GiveUsAPickUpObject(int32 handle) object->bExplosionProof = true; object->bUsesCollision = false; object->bIsPickup = true; + object->bHasPreRenderEffects = true; object->m_nBonusValue = m_eModelIndex == MI_PICKUP_BONUS ? m_nQuantity : 0; @@ -129,12 +150,12 @@ CPickup::GiveUsAPickUpObject(int32 handle) } bool -CPickup::CanBePickedUp(CPlayerPed *player) +CPickup::CanBePickedUp(CPlayerPed *player, int playerId) { assert(m_pObject != nil); bool cannotBePickedUp = - (m_pObject->GetModelIndex() == MI_PICKUP_BODYARMOUR && player->m_fArmour > 99.5f) - || (m_pObject->GetModelIndex() == MI_PICKUP_HEALTH && player->m_fHealth > 99.5f) + (m_pObject->GetModelIndex() == MI_PICKUP_BODYARMOUR && player->m_fArmour > CWorld::Players[playerId].m_nMaxArmour - 0.5f) + || (m_pObject->GetModelIndex() == MI_PICKUP_HEALTH && player->m_fHealth > CWorld::Players[playerId].m_nMaxHealth - 0.5f) || (m_pObject->GetModelIndex() == MI_PICKUP_BRIBE && player->m_pWanted->m_nWantedLevel == 0) || (m_pObject->GetModelIndex() == MI_PICKUP_KILLFRENZY && (CTheScripts::IsPlayerOnAMission() || CDarkel::FrenzyOnGoing() || !CGame::nastyGame)); return !cannotBePickedUp; @@ -190,7 +211,7 @@ CPickup::Update(CPlayerPed *player, CVehicle *vehicle, int playerId) } // if we didn't then we've got nothing to do - if (isPickupTouched && CanBePickedUp(player)) { + if (isPickupTouched && CanBePickedUp(player, playerId)) { CPad::GetPad(0)->StartShake(120, 100); switch (m_eType) { @@ -380,6 +401,30 @@ CPickups::Init(void) CollectedPickUpIndex = 0; } +// --MIAMI: Done +bool +CPickups::TestForPickupsInBubble(CVector pos, float range) +{ + for (int i = 0; i < NUMPICKUPS; i++) { + if ((aPickUps[i].m_vecPos - pos).Magnitude() < range) + return true; + } + return false; +} + +// --MIAMI: Done +bool +CPickups::TryToMerge_WeaponType(CVector pos, eWeaponType weapon, uint8 type, uint32 quantity, bool unused) { + for (int i = 0; i < NUMPICKUPS; i++) { + if (aPickUps[i].m_eType == type && aPickUps[i].m_eModelIndex == ModelForWeapon(weapon)) + if ((aPickUps[i].m_vecPos - pos).Magnitude() < 7.5f) { + aPickUps[i].m_nQuantity += quantity; + return true; + } + } + return false; +} + bool CPickups::IsPickUpPickedUp(int32 pickupId) { @@ -430,14 +475,14 @@ CPickups::GivePlayerGoodiesWithPickUpMI(int16 modelIndex, int playerIndex) DMAudio.PlayFrontEndSound(SOUND_PICKUP_ADRENALINE, 0); return true; } else if (modelIndex == MI_PICKUP_BODYARMOUR) { - player->m_fArmour = 100.0f; + player->m_fArmour = CWorld::Players[playerIndex].m_nMaxArmour; DMAudio.PlayFrontEndSound(SOUND_PICKUP_ARMOUR, 0); return true; } else if (modelIndex == MI_PICKUP_INFO) { DMAudio.PlayFrontEndSound(SOUND_PICKUP_BONUS, 0); return true; } else if (modelIndex == MI_PICKUP_HEALTH) { - player->m_fHealth = 100.0f; + player->m_fHealth = CWorld::Players[playerIndex].m_nMaxHealth; DMAudio.PlayFrontEndSound(SOUND_PICKUP_HEALTH, 0); return true; } else if (modelIndex == MI_PICKUP_BONUS) { @@ -561,53 +606,22 @@ CPickups::GetNewUniquePickupIndex(int32 slot) return slot | (aPickUps[slot].m_nIndex << 16); } +// --MIAMI: Done int32 CPickups::ModelForWeapon(eWeaponType weaponType) { - switch (weaponType) - { - case WEAPONTYPE_BASEBALLBAT: return MI_BASEBALL_BAT; - case WEAPONTYPE_COLT45: return MI_COLT; - case WEAPONTYPE_UZI: return MI_UZI; - case WEAPONTYPE_SHOTGUN: return MI_SHOTGUN; - case WEAPONTYPE_AK47: return MI_AK47; - case WEAPONTYPE_M16: return MI_M16; - case WEAPONTYPE_SNIPERRIFLE: return MI_SNIPER; - case WEAPONTYPE_ROCKETLAUNCHER: return MI_ROCKETLAUNCHER; - case WEAPONTYPE_FLAMETHROWER: return MI_FLAMETHROWER; - case WEAPONTYPE_MOLOTOV: return MI_MOLOTOV; - case WEAPONTYPE_GRENADE: return MI_GRENADE; - default: break; - } - return 0; + return CWeaponInfo::GetWeaponInfo(weaponType)->m_nModelId; } +// --MIAMI: Done eWeaponType CPickups::WeaponForModel(int32 model) { if (model == MI_PICKUP_BODYARMOUR) return WEAPONTYPE_ARMOUR; - switch (model) - { - case MI_GRENADE: return WEAPONTYPE_GRENADE; - case MI_AK47: return WEAPONTYPE_AK47; - case MI_BASEBALL_BAT: return WEAPONTYPE_BASEBALLBAT; - case MI_COLT: return WEAPONTYPE_COLT45; - case MI_MOLOTOV: return WEAPONTYPE_MOLOTOV; - case MI_ROCKETLAUNCHER: return WEAPONTYPE_ROCKETLAUNCHER; - case MI_SHOTGUN: return WEAPONTYPE_SHOTGUN; - case MI_SNIPER: return WEAPONTYPE_SNIPERRIFLE; - case MI_UZI: return WEAPONTYPE_UZI; - case MI_MISSILE: return WEAPONTYPE_UNARMED; - case MI_M16: return WEAPONTYPE_M16; - case MI_FLAMETHROWER: return WEAPONTYPE_FLAMETHROWER; - } - return WEAPONTYPE_UNARMED; -} - -int32 -CPickups::FindColourIndexForWeaponMI(int32 model) -{ - return WeaponForModel(model) - 1; + if (model == MI_PICKUP_HEALTH) return WEAPONTYPE_HEALTH; + if (model == MI_PICKUP_ADRENALINE) return WEAPONTYPE_ARMOUR; + if (model == -1) return WEAPONTYPE_UNARMED; + return (eWeaponType)((CWeaponModelInfo*)CModelInfo::GetModelInfo(model))->GetWeaponInfo(); } void @@ -685,15 +699,15 @@ CPickups::DoPickUpEffects(CEntity *entity) int16 colorId; if (entity->GetModelIndex() == MI_PICKUP_ADRENALINE || entity->GetModelIndex() == MI_PICKUP_CAMERA) - colorId = 11; + colorId = WEAPONTYPE_TOTALWEAPONS; else if (entity->GetModelIndex() == MI_PICKUP_BODYARMOUR || entity->GetModelIndex() == MI_PICKUP_BRIBE) - colorId = 12; + colorId = WEAPONTYPE_TOTALWEAPONS + 1; else if (entity->GetModelIndex() == MI_PICKUP_INFO || entity->GetModelIndex() == MI_PICKUP_KILLFRENZY) - colorId = 13; + colorId = WEAPONTYPE_TOTALWEAPONS + 2; else if (entity->GetModelIndex() == MI_PICKUP_HEALTH || entity->GetModelIndex() == MI_PICKUP_BONUS) - colorId = 14; + colorId = WEAPONTYPE_TOTALWEAPONS + 3; else - colorId = FindColourIndexForWeaponMI(entity->GetModelIndex()); + colorId = WeaponForModel(entity->GetModelIndex()); assert(colorId >= 0); @@ -981,6 +995,25 @@ CPickups::RenderPickUpText() NumMessages = 0; } +void +CPickups::CreateSomeMoney(CVector pos, int money) +{ + bool found; + + int pickupCount = Min(money / 20 + 1, 7); + int moneyPerPickup = money / pickupCount; + + for (int i = 0; i < pickupCount; i++) { + // (CGeneral::GetRandomNumber() % 256) * PI / 128 gives a float up to something TWOPI-ish. + pos.x += 1.5f * Sin((CGeneral::GetRandomNumber() % 256) * PI / 128); + pos.y += 1.5f * Cos((CGeneral::GetRandomNumber() % 256) * PI / 128); + pos.z = CWorld::FindGroundZFor3DCoord(pos.x, pos.y, pos.z, &found) + 0.5f; + if (found) { + CPickups::GenerateNewOne(CVector(pos.x, pos.y, pos.z), MI_MONEY, PICKUP_MONEY, moneyPerPickup + (CGeneral::GetRandomNumber() & 3)); + } + } +} + void CPickups::Load(uint8 *buf, uint32 size) { @@ -1126,45 +1159,6 @@ CPacManPickups::Update() void CPacManPickups::GeneratePMPickUps(CVector pos, float scrambleMult, int16 count, uint8 type) { - int i = 0; - while (count > 0) { - while (aPMPickUps[i].m_eType != PACMAN_NONE) - i++; - - bool bPickupCreated = false; - while (!bPickupCreated) { - CVector newPos = pos; - CColPoint colPoint; - CEntity *pRoad; - uint16 nRand = CGeneral::GetRandomNumber(); - newPos.x += ((nRand & 0xFF) - 128) * scrambleMult / 128.0f; - newPos.y += (((nRand >> 8) & 0xFF) - 128) * scrambleMult / 128.0f; - newPos.z = 1000.0f; - if (CWorld::ProcessVerticalLine(newPos, -1000.0f, colPoint, pRoad, true, false, false, false, true, false, nil) && pRoad->IsBuilding() && ((CBuilding*)pRoad)->GetIsATreadable()) { - newPos.z = 0.7f + colPoint.point.z; - aPMPickUps[i].m_eType = type; - aPMPickUps[i].m_vecPosn = newPos; - CObject *obj = new CObject(MI_BULLION, true); - if (obj != nil) { - obj->ObjectCreatedBy = MISSION_OBJECT; - obj->SetPosition(aPMPickUps[i].m_vecPosn); - obj->SetOrientation(0.0f, 0.0f, -HALFPI); - obj->GetMatrix().UpdateRW(); - obj->UpdateRwFrame(); - - obj->bAffectedByGravity = false; - obj->bExplosionProof = true; - obj->bUsesCollision = false; - obj->bIsPickup = false; - CWorld::Add(obj); - } - aPMPickUps[i].m_pObject = obj; - bPickupCreated = true; - } - } - count--; - } - bPMActive = true; } // diablo porn mission pickups @@ -1281,40 +1275,6 @@ static const CVector aRacePoints1[] = { void CPacManPickups::GeneratePMPickUpsForRace(int32 race) { - const CVector *pPos = nil; - int i = 0; - - if (race == 0) pPos = aRacePoints1; // there's only one available - assert(pPos != nil); - - while (!pPos->IsZero()) { - while (aPMPickUps[i].m_eType != PACMAN_NONE) - i++; - - aPMPickUps[i].m_eType = PACMAN_RACE; - aPMPickUps[i].m_vecPosn = *(pPos++); - if (race == 0) { - CObject* obj = new CObject(MI_DONKEYMAG, true); - if (obj != nil) { - obj->ObjectCreatedBy = MISSION_OBJECT; - - obj->SetPosition(aPMPickUps[i].m_vecPosn); - obj->SetOrientation(0.0f, 0.0f, -HALFPI); - obj->GetMatrix().UpdateRW(); - obj->UpdateRwFrame(); - - obj->bAffectedByGravity = false; - obj->bExplosionProof = true; - obj->bUsesCollision = false; - obj->bIsPickup = false; - - CWorld::Add(obj); - } - aPMPickUps[i].m_pObject = obj; - } else - aPMPickUps[i].m_pObject = nil; - } - bPMActive = true; } void diff --git a/src/control/Pickups.h b/src/control/Pickups.h index 2842edfa..0a73696a 100644 --- a/src/control/Pickups.h +++ b/src/control/Pickups.h @@ -46,7 +46,7 @@ public: bool Update(CPlayerPed *player, CVehicle *vehicle, int playerId); private: bool IsMine() { return m_eType >= PICKUP_MINE_INACTIVE && m_eType <= PICKUP_FLOATINGPACKAGE_FLOATING; } - inline bool CanBePickedUp(CPlayerPed *player); + inline bool CanBePickedUp(CPlayerPed *player, int playerId); void RemoveKeepType(); void Remove(); }; @@ -85,11 +85,13 @@ public: static bool IsPickUpPickedUp(int32 pickupId); static int32 ModelForWeapon(eWeaponType weaponType); static enum eWeaponType WeaponForModel(int32 model); - static int32 FindColourIndexForWeaponMI(int32 model); static int32 GetActualPickupIndex(int32 index); static int32 GetNewUniquePickupIndex(int32 slot); static void PassTime(uint32 time); static bool GivePlayerGoodiesWithPickUpMI(int16 modelIndex, int playerIndex); + static bool TestForPickupsInBubble(CVector pos, float range); + static bool TryToMerge_WeaponType(CVector pos, eWeaponType weapon, uint8 type, uint32 quantity, bool unused); + static void CreateSomeMoney(CVector, int); static void Load(uint8 *buf, uint32 size); static void Save(uint8 *buf, uint32 *size); @@ -103,7 +105,7 @@ public: }; extern uint16 AmmoForWeapon[20]; -extern uint16 AmmoForWeapon_OnStreet[20]; +extern uint16 AmmoForWeapon_OnStreet[WEAPONTYPE_TOTALWEAPONS]; extern uint16 CostOfWeapon[20]; enum ePacmanPickupType diff --git a/src/control/Replay.cpp b/src/control/Replay.cpp index ab187c10..28b999f8 100644 --- a/src/control/Replay.cpp +++ b/src/control/Replay.cpp @@ -17,6 +17,7 @@ #include "ModelInfo.h" #include "Object.h" #include "Pad.h" +#include "PedAttractor.h" #include "Phones.h" #include "Pickups.h" #include "Plane.h" @@ -510,8 +511,12 @@ void CReplay::ProcessPedUpdate(CPed *ped, float interpolation, CAddressInReplayB } RetrievePedAnimation(ped, &pp->anim_state); ped->RemoveWeaponModel(-1); - if (pp->weapon_model != (uint8)-1) - ped->AddWeaponModel(pp->weapon_model); + if (pp->weapon_model != (uint16)-1) { + if (CStreaming::HasModelLoaded(pp->weapon_model)) + ped->AddWeaponModel(pp->weapon_model); + else + CStreaming::RequestModel(pp->weapon_model, 0); + } CWorld::Remove(ped); CWorld::Add(ped); buffer->m_nOffset += sizeof(tPedUpdatePacket); @@ -1116,6 +1121,14 @@ void CReplay::StoreStuffInMem(void) for (int i = 0; i < NUMPLAYERS; i++) nHandleOfPlayerPed[i] = CPools::GetPedPool()->GetIndex(CWorld::Players[i].m_pPed); #endif + int i = CPools::GetPedPool()->GetSize(); + while (--i >= 0) { + CPed* ped = CPools::GetPedPool()->GetSlot(i); + if (!ped) + continue; + if (ped->m_attractor) + GetPedAttractorManager()->DeRegisterPed(ped, ped->m_attractor); + } CPools::GetVehiclePool()->Store(pBuf0, pBuf1); CPools::GetPedPool()->Store(pBuf2, pBuf3); CPools::GetObjectPool()->Store(pBuf4, pBuf5); @@ -1211,6 +1224,16 @@ void CReplay::RestoreStuffFromMem(void) ped->m_audioEntityId = DMAudio.CreateEntity(AUDIOTYPE_PHYSICAL, ped); DMAudio.SetEntityStatus(ped->m_audioEntityId, true); CPopulation::UpdatePedCount((ePedType)ped->m_nPedType, false); + for (int j = 0; j < TOTAL_WEAPON_SLOTS; j++) { + int mi1 = CWeaponInfo::GetWeaponInfo(ped->m_weapons[j].m_eWeaponType)->m_nModelId; + if (mi1 != -1) + CStreaming::RequestModel(mi1, STREAMFLAGS_DEPENDENCY); + int mi2 = CWeaponInfo::GetWeaponInfo(ped->m_weapons[j].m_eWeaponType)->m_nModel2Id; + if (mi2 != -1) + CStreaming::RequestModel(mi2, STREAMFLAGS_DEPENDENCY); + CStreaming::LoadAllRequestedModels(false); + ped->m_weapons[j].Initialise(ped->m_weapons[j].m_eWeaponType, ped->m_weapons[j].m_nAmmoTotal); + } if (ped->m_wepModelID >= 0) ped->AddWeaponModel(ped->m_wepModelID); } diff --git a/src/control/Replay.h b/src/control/Replay.h index 09cf601e..b369c13d 100644 --- a/src/control/Replay.h +++ b/src/control/Replay.h @@ -176,7 +176,7 @@ class CReplay CStoredAnimationState anim_state; CCompressedMatrixNotAligned matrix; int8 assoc_group_id; - uint8 weapon_model; + uint16 weapon_model; }; VALIDATE_SIZE(tPedUpdatePacket, 40); diff --git a/src/control/RoadBlocks.cpp b/src/control/RoadBlocks.cpp index 0261cd4a..a26e19f5 100644 --- a/src/control/RoadBlocks.cpp +++ b/src/control/RoadBlocks.cpp @@ -47,7 +47,7 @@ CRoadBlocks::Init(void) } void -CRoadBlocks::GenerateRoadBlockCopsForCar(CVehicle* pVehicle, int32 roadBlockType, int16 roadBlockNode) +CRoadBlocks::GenerateRoadBlockCopsForCar(CVehicle* pVehicle, int32 roadBlockType) { static const CVector vecRoadBlockOffets[6] = { {-1.5, 1.8f, 0.0f}, {-1.5f, -1.8f, 0.0f}, {1.5f, 1.8f, 0.0f}, {1.5f, -1.8f, 0.0f}, {-1.5f, 0.0f, 0.0f}, {1.5, 0.0, 0.0} }; @@ -90,7 +90,7 @@ CRoadBlocks::GenerateRoadBlockCopsForCar(CVehicle* pVehicle, int32 roadBlockType pCopPed->SetIdle(); pCopPed->bKindaStayInSamePlace = true; pCopPed->bNotAllowedToDuck = false; - pCopPed->m_nRoadblockNode = roadBlockNode; +// pCopPed->m_nRoadblockNode = roadBlockNode; pCopPed->bCrouchWhenShooting = roadBlockType != 2; if (pEntityToAttack) { pCopPed->m_pPointGunAt = pEntityToAttack; diff --git a/src/control/RoadBlocks.h b/src/control/RoadBlocks.h index 439fd6e7..c8469ba5 100644 --- a/src/control/RoadBlocks.h +++ b/src/control/RoadBlocks.h @@ -15,6 +15,6 @@ public: static bool InOrOut[NUMROADBLOCKS]; static void Init(void); - static void GenerateRoadBlockCopsForCar(CVehicle* pVehicle, int32 roadBlockType, int16 roadBlockNode); + static void GenerateRoadBlockCopsForCar(CVehicle* pVehicle, int32 roadBlockType); static void GenerateRoadBlocks(void); }; diff --git a/src/control/Script.cpp b/src/control/Script.cpp index 8342ef46..d7abbfb2 100644 --- a/src/control/Script.cpp +++ b/src/control/Script.cpp @@ -38,6 +38,7 @@ #include "Pad.h" #include "Particle.h" #include "ParticleObject.h" +#include "PedAttractor.h" #include "PedRoutes.h" #include "Phones.h" #include "Pickups.h" @@ -54,15 +55,21 @@ #include "Remote.h" #include "Replay.h" #include "Restart.h" +#include "RoadBlocks.h" #include "RpAnimBlend.h" #include "Rubbish.h" +#include "SimpleModelInfo.h" +#include "SetPieces.h" #include "Shadows.h" #include "SpecialFX.h" +#include "Sprite.h" #include "Stats.h" #include "Streaming.h" #include "Text.h" +#include "Timecycle.h" #include "TxdStore.h" #include "User.h" +#include "VisibilityPlugins.h" #include "WaterLevel.h" #include "Weather.h" #include "World.h" @@ -71,13 +78,7 @@ #define PICKUP_PLACEMENT_OFFSET 0.5f #define PED_FIND_Z_OFFSET 5.0f - -#define SPHERE_MARKER_R 0 -#define SPHERE_MARKER_G 128 -#define SPHERE_MARKER_B 255 -#define SPHERE_MARKER_A 128 -#define SPHERE_MARKER_PULSE_PERIOD 2048 -#define SPHERE_MARKER_PULSE_FRACTION 0.1f +#define COP_PED_FIND_Z_OFFSET 10.0f #ifdef USE_PRECISE_MEASUREMENT_CONVERTION #define METERS_IN_FOOT 0.3048f @@ -89,13 +90,10 @@ uint8 CTheScripts::ScriptSpace[SIZE_SCRIPT_SPACE]; CRunningScript CTheScripts::ScriptsArray[MAX_NUM_SCRIPTS]; -int32 CTheScripts::BaseBriefIdForContact[MAX_NUM_CONTACTS]; -int32 CTheScripts::OnAMissionForContactFlag[MAX_NUM_CONTACTS]; intro_text_line CTheScripts::IntroTextLines[MAX_NUM_INTRO_TEXT_LINES]; intro_script_rectangle CTheScripts::IntroRectangles[MAX_NUM_INTRO_RECTANGLES]; CSprite2d CTheScripts::ScriptSprites[MAX_NUM_SCRIPT_SRPITES]; script_sphere_struct CTheScripts::ScriptSphereArray[MAX_NUM_SCRIPT_SPHERES]; -tCollectiveData CTheScripts::CollectiveArray[MAX_NUM_COLLECTIVES]; tUsedObject CTheScripts::UsedObjectArray[MAX_NUM_USED_OBJECTS]; int32 CTheScripts::MultiScriptArray[MAX_NUM_MISSION_SCRIPTS]; tBuildingSwap CTheScripts::BuildingSwapArray[MAX_NUM_BUILDING_SWAPS]; @@ -116,8 +114,6 @@ uint16 CTheScripts::NumberOfMissionScripts; uint32 CTheScripts::LargestMissionScriptSize; uint32 CTheScripts::MainScriptSize; uint8 CTheScripts::FailCurrentMission; -uint8 CTheScripts::CountdownToMakePlayerUnsafe; -uint8 CTheScripts::DelayMakingPlayerUnsafeThisTime; uint16 CTheScripts::NumScriptDebugLines; uint16 CTheScripts::NumberOfIntroRectanglesThisFrame; uint16 CTheScripts::NumberOfIntroTextLinesThisFrame; @@ -128,6 +124,11 @@ CStuckCarCheck CTheScripts::StuckCars; uint16 CTheScripts::CommandsExecuted; uint16 CTheScripts::ScriptsUpdated; int32 ScriptParams[32]; +uint8 CTheScripts::RiotIntensity; +uint32 CTheScripts::LastMissionPassedTime; +uint16 CTheScripts::NumberOfExclusiveMissionScripts; +bool CTheScripts::bPlayerHasMetDebbieHarry; +bool CTheScripts::bPlayerIsInTheStatium; const uint32 CRunningScript::nSaveStructSize = @@ -269,9 +270,19 @@ void CMissionCleanup::Process() CPopulation::m_AllRandomPedsThisType = -1; CPopulation::PedDensityMultiplier = 1.0f; CCarCtrl::CarDensityMultiplier = 1.0f; + CPed::nThreatReactionRangeMultiplier = 1; + CPed::nEnterCarRangeMultiplier = 1; FindPlayerPed()->m_pWanted->m_fCrimeSensitivity = 1.0f; - TheCamera.Restore(); + //CRoadBlocks::ClearScriptRoadblocks() // TODO(MIAMI) + CRouteNode::Initialise(); + if (!CWorld::Players[CWorld::PlayerInFocus].m_pRemoteVehicle) + TheCamera.Restore(); TheCamera.SetWideScreenOff(); + // TODO(MIAMI) + //CSpecialFX::bLiftCam = false; + //CSpecialFX::bVideoCam = false; + //CTimeCycle::StopExtraColour(0); + // TODO(MIAMI): change this to loop when it supports parameters DMAudio.ClearMissionAudio(); CWeather::ReleaseWeather(); for (int i = 0; i < NUM_OF_SPECIAL_CHARS; i++) @@ -280,11 +291,18 @@ void CMissionCleanup::Process() CStreaming::SetMissionDoesntRequireModel(MI_CUTOBJ01 + i); CStreaming::ms_disableStreaming = false; CHud::m_ItemToFlash = -1; - CHud::SetHelpMessage(nil, false); + CHud::SetHelpMessage(nil, false); // TODO(MIAMI): third parameter is false CUserDisplay::OnscnTimer.m_bDisabled = false; + CTheScripts::RemoveScriptTextureDictionary(); CWorld::Players[0].m_pPed->m_pWanted->m_bIgnoredByCops = false; CWorld::Players[0].m_pPed->m_pWanted->m_bIgnoredByEveryone = false; CWorld::Players[0].MakePlayerSafe(false); + //TODO(MIAMI): drunkenness, enable drive by + //DMAudio::ShutUpPlayerTalking(0); + CVehicle::bDisableRemoteDetonation = false; + CVehicle::bDisableRemoteDetonationOnContact = false; + //CGameLogic::ClearShortCut(); // TODO(MIAMI) + CTheScripts::RiotIntensity = 0; CTheScripts::StoreVehicleIndex = -1; CTheScripts::StoreVehicleWasRandom = true; CTheScripts::UpsideDownCars.Init(); @@ -507,7 +525,6 @@ void CRunningScript::CollectParameters(uint32* pIp, int16 total) int32 CRunningScript::CollectNextParameterWithoutIncreasingPC(uint32 ip) { uint32* pIp = &ip; - float tmp; switch (CTheScripts::Read1ByteFromScript(pIp)) { case ARGUMENT_INT32: @@ -521,8 +538,7 @@ int32 CRunningScript::CollectNextParameterWithoutIncreasingPC(uint32 ip) case ARGUMENT_INT16: return CTheScripts::Read2BytesFromScript(pIp); case ARGUMENT_FLOAT: - tmp = CTheScripts::ReadFloatFromScript(pIp); - return *(int32*)&tmp; + return CTheScripts::Read4BytesFromScript(pIp); default: assert(0); } @@ -631,14 +647,7 @@ void CTheScripts::Init() StoreVehicleIndex = -1; StoreVehicleWasRandom = true; OnAMissionFlag = 0; - for (int i = 0; i < MAX_NUM_CONTACTS; i++){ - BaseBriefIdForContact[i] = 0; - OnAMissionForContactFlag[i] = 0; - } - for (int i = 0; i < MAX_NUM_COLLECTIVES; i++){ - CollectiveArray[i].index = -1; - CollectiveArray[i].unk_data = 0; - } + LastMissionPassedTime = (uint32)-1; NextFreeCollectiveIndex = 0; LastRandomPedId = -1; for (int i = 0; i < MAX_NUM_USED_OBJECTS; i++){ @@ -652,15 +661,17 @@ void CTheScripts::Init() bUsingAMultiScriptFile = true; for (int i = 0; i < MAX_NUM_MISSION_SCRIPTS; i++) MultiScriptArray[i] = 0; + NumberOfExclusiveMissionScripts = 0; NumberOfMissionScripts = 0; LargestMissionScriptSize = 0; MainScriptSize = 0; ReadMultiScriptFileOffsetsFromScript(); FailCurrentMission = 0; - CountdownToMakePlayerUnsafe = 0; DbgFlag = false; - DelayMakingPlayerUnsafeThisTime = 1; NumScriptDebugLines = 0; + RiotIntensity = 0; + bPlayerHasMetDebbieHarry = false; + bPlayerIsInTheStatium = false; for (int i = 0; i < MAX_NUM_SCRIPT_SPHERES; i++){ ScriptSphereArray[i].m_bInUse = false; ScriptSphereArray[i].m_Index = 1; @@ -681,6 +692,7 @@ void CTheScripts::Init() IntroRectangles[i].m_sColor = CRGBA(255, 255, 255, 255); } NumberOfIntroRectanglesThisFrame = 0; + RemoveScriptTextureDictionary(); for (int i = 0; i < MAX_NUM_BUILDING_SWAPS; i++){ BuildingSwapArray[i].m_pBuilding = nil; BuildingSwapArray[i].m_nNewModel = -1; @@ -690,6 +702,15 @@ void CTheScripts::Init() InvisibilitySettingArray[i] = nil; } +void CTheScripts::RemoveScriptTextureDictionary() +{ + for (int i = 0; i < ARRAY_SIZE(CTheScripts::ScriptSprites); i++) + CTheScripts::ScriptSprites[i].Delete(); + int slot = CTxdStore::FindTxdSlot("script"); + if (slot != -1) + CTxdStore::RemoveTxd(slot); +} + void CRunningScript::RemoveScriptFromList(CRunningScript** ppScript) { if (prev) @@ -733,10 +754,6 @@ void CTheScripts::Process() DrawScriptSpheres(); if (FailCurrentMission) --FailCurrentMission; - if (CountdownToMakePlayerUnsafe){ - if (--CountdownToMakePlayerUnsafe == 0) - CWorld::Players[0].MakePlayerSafe(false); - } if (UseTextCommands){ for (int i = 0; i < MAX_NUM_INTRO_TEXT_LINES; i++) IntroTextLines[i].Reset(); @@ -843,6 +860,7 @@ int8 CRunningScript::ProcessCommands0To99(int32 command) case COMMAND_WAIT: CollectParameters(&m_nIp, 1); m_nWakeTime = CTimer::GetTimeInMilliseconds() + ScriptParams[0]; + m_bSkipWakeTime = false; return 1; case COMMAND_GOTO: CollectParameters(&m_nIp, 1); @@ -1256,13 +1274,11 @@ int8 CRunningScript::ProcessCommands0To99(int32 command) UpdateCompareFlag(*ptr1 == *ptr2); return 0; } - /* Following commands are not implemented, and go to default case - case COMMAND_IS_INT_VAR_NOT_EQUAL_TO_NUMBER: - case COMMAND_IS_INT_LVAR_NOT_EQUAL_TO_NUMBER: - case COMMAND_IS_INT_VAR_NOT_EQUAL_TO_INT_VAR: - case COMMAND_IS_INT_LVAR_NOT_EQUAL_TO_INT_LVAR: - case COMMAND_IS_INT_VAR_NOT_EQUAL_TO_INT_LVAR: - */ + //case COMMAND_IS_INT_VAR_NOT_EQUAL_TO_NUMBER: + //case COMMAND_IS_INT_LVAR_NOT_EQUAL_TO_NUMBER: + //case COMMAND_IS_INT_VAR_NOT_EQUAL_TO_INT_VAR: + //case COMMAND_IS_INT_LVAR_NOT_EQUAL_TO_INT_LVAR: + //case COMMAND_IS_INT_VAR_NOT_EQUAL_TO_INT_LVAR: case COMMAND_IS_FLOAT_VAR_EQUAL_TO_NUMBER: { int32* ptr = GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL); @@ -1298,19 +1314,18 @@ int8 CRunningScript::ProcessCommands0To99(int32 command) UpdateCompareFlag(*(float*)ptr1 == *(float*)ptr2); return 0; } - /* Following commands are not implemented, and go to default case - case COMMAND_IS_FLOAT_VAR_NOT_EQUAL_TO_NUMBER: - case COMMAND_IS_FLOAT_LVAR_NOT_EQUAL_TO_NUMBER: - case COMMAND_IS_FLOAT_VAR_NOT_EQUAL_TO_FLOAT_VAR: - case COMMAND_IS_FLOAT_LVAR_NOT_EQUAL_TO_FLOAT_LVAR: - case COMMAND_IS_FLOAT_VAR_NOT_EQUAL_TO_FLOAT_LVAR: - */ + //case COMMAND_IS_FLOAT_VAR_NOT_EQUAL_TO_NUMBER: + //case COMMAND_IS_FLOAT_LVAR_NOT_EQUAL_TO_NUMBER: + //case COMMAND_IS_FLOAT_VAR_NOT_EQUAL_TO_FLOAT_VAR: + //case COMMAND_IS_FLOAT_LVAR_NOT_EQUAL_TO_FLOAT_LVAR: + //case COMMAND_IS_FLOAT_VAR_NOT_EQUAL_TO_FLOAT_LVAR: + /* case COMMAND_GOTO_IF_TRUE: CollectParameters(&m_nIp, 1); if (m_bCondResult) SetIP(ScriptParams[0] >= 0 ? ScriptParams[0] : SIZE_MAIN_SCRIPT - ScriptParams[0]); - /* Check COMMAND_GOTO note. */ return 0; + */ case COMMAND_GOTO_IF_FALSE: CollectParameters(&m_nIp, 1); if (!m_bCondResult) @@ -1322,12 +1337,14 @@ int8 CRunningScript::ProcessCommands0To99(int32 command) CTheScripts::bAlreadyRunningAMissionScript = false; RemoveScriptFromList(&CTheScripts::pActiveScripts); AddScriptToList(&CTheScripts::pIdleScripts); + m_bIsActive = false; return 1; case COMMAND_START_NEW_SCRIPT: { CollectParameters(&m_nIp, 1); assert(ScriptParams[0] >= 0); CRunningScript* pNew = CTheScripts::StartNewScript(ScriptParams[0]); + m_bIsActive = true; int8 type = CTheScripts::Read1ByteFromScript(&m_nIp); float tmp; for (int i = 0; type != ARGUMENT_END; type = CTheScripts::Read1ByteFromScript(&m_nIp), i++) { @@ -1375,7 +1392,7 @@ int8 CRunningScript::ProcessCommands0To99(int32 command) { CollectParameters(&m_nIp, 4); int32 index = ScriptParams[0]; - assert(index < 1); /* Constant? Also no more double player glitch */ + assert(index < NUMPLAYERS); printf("&&&&&&&&&&&&&Creating player: %d\n", index); if (!CStreaming::HasModelLoaded(MI_PLAYER)) { CStreaming::RequestSpecialModel(MI_PLAYER, "player", STREAMFLAGS_DONT_REMOVE | STREAMFLAGS_DEPENDENCY); @@ -1415,20 +1432,49 @@ int8 CRunningScript::ProcessCommands0To99(int32 command) if (pos.z <= MAP_Z_LOW_LIMIT) pos.z = CWorld::FindGroundZForCoord(pos.x, pos.y); CPlayerPed* ped = CWorld::Players[index].m_pPed; - if (!ped->bInVehicle) { - pos.z += ped->GetDistanceFromCentreOfMassToBaseOfModel(); - ped->Teleport(pos); - CTheScripts::ClearSpaceForMissionEntity(pos, ped); + if (ped->bInVehicle) { + pos.z += ped->m_pMyVehicle->GetDistanceFromCentreOfMassToBaseOfModel(); + ped->m_pMyVehicle->Teleport(pos); // removed dumb stuff that was present here + CTheScripts::ClearSpaceForMissionEntity(pos, ped->m_pMyVehicle); return 0; } - pos.z += ped->m_pMyVehicle->GetDistanceFromCentreOfMassToBaseOfModel(); - if (ped->m_pMyVehicle->IsBoat()) - ped->m_pMyVehicle->Teleport(pos); - else - ped->m_pMyVehicle->Teleport(pos); - /* I'll keep this condition here but obviously it is absolutely pointless */ - /* It's clearly present in disassembly so it had to be in original code */ - CTheScripts::ClearSpaceForMissionEntity(pos, ped->m_pMyVehicle); + pos.z += ped->GetDistanceFromCentreOfMassToBaseOfModel(); + CVector vOldPos = ped->GetPosition(); + ped->Teleport(pos); + CTheScripts::ClearSpaceForMissionEntity(pos, ped); + if (ped) { // great time to check + for (int i = 0; i < ped->m_numNearPeds; i++) { + CPed* pTestedPed = ped->m_nearPeds[i]; + if (!pTestedPed || !IsPedPointerValid(pTestedPed)) + continue; + if (pTestedPed->m_pedInObjective == ped && pTestedPed->m_objective == OBJ_15) { + CVector vFollowerPos = pTestedPed->GetFormationPosition(); + CTheScripts::ClearSpaceForMissionEntity(vFollowerPos, ped); + bool bFound = false; + vFollowerPos.z = CWorld::FindGroundZFor3DCoord(vFollowerPos.x, vFollowerPos.y, vFollowerPos.z + 1.0f, &bFound) + 1.0f; + if (bFound) { + if (CWorld::GetIsLineOfSightClear(vFollowerPos, ped->GetPosition(), true, false, false, true, false, false)) { + pTestedPed->Teleport(vFollowerPos); + } + } + } + else if (pTestedPed->m_leader == ped) { + CVector vFollowerPos; + if (pTestedPed->m_pedFormation) + vFollowerPos = pTestedPed->GetFormationPosition(); + else + vFollowerPos = ped->GetPosition() + pTestedPed->GetPosition() - vOldPos; + CTheScripts::ClearSpaceForMissionEntity(vFollowerPos, ped); + bool bFound = false; + vFollowerPos.z = CWorld::FindGroundZFor3DCoord(vFollowerPos.x, vFollowerPos.y, vFollowerPos.z + 1.0f, &bFound) + 1.0f; + if (bFound) { + if (CWorld::GetIsLineOfSightClear(vFollowerPos, ped->GetPosition(), true, false, false, true, false, false)) { + pTestedPed->Teleport(vFollowerPos); + } + } + } + } + } return 0; } case COMMAND_IS_PLAYER_IN_AREA_2D: @@ -1850,6 +1896,7 @@ int8 CRunningScript::ProcessCommands100To199(int32 command) ped->CharCreatedBy = MISSION_CHAR; ped->bRespondsToThreats = false; ped->bAllowMedicsToReviveMe = false; + ped->bIsPlayerFriend = false; CVector pos = *(CVector*)&ScriptParams[2]; if (pos.z <= MAP_Z_LOW_LIMIT) pos.z = CWorld::FindGroundZForCoord(pos.x, pos.y); @@ -1872,24 +1919,7 @@ int8 CRunningScript::ProcessCommands100To199(int32 command) { CollectParameters(&m_nIp, 1); CPed* ped = CPools::GetPedPool()->GetAt(ScriptParams[0]); - if (ped) { - if (ped->InVehicle()) { - if (ped->m_pMyVehicle->pDriver == ped) { - ped->m_pMyVehicle->RemoveDriver(); - ped->m_pMyVehicle->SetStatus(STATUS_ABANDONED); - if (ped->m_pMyVehicle->m_nDoorLock == CARLOCK_LOCKED_INITIALLY) - ped->m_pMyVehicle->m_nDoorLock = CARLOCK_UNLOCKED; - if (ped->m_nPedType == PEDTYPE_COP && ped->m_pMyVehicle->IsLawEnforcementVehicle()) - ped->m_pMyVehicle->ChangeLawEnforcerState(0); - } - else { - ped->m_pMyVehicle->RemovePassenger(ped); - } - } - CWorld::RemoveReferencesToDeletedObject(ped); - delete ped; - --CPopulation::ms_nTotalMissionPeds; - } + CTheScripts::RemoveThisPed(ped); if (m_bIsMissionScript) CTheScripts::MissionCleanup.RemoveEntityFromList(ScriptParams[0], CLEANUP_CHAR); return 0; @@ -1906,19 +1936,26 @@ int8 CRunningScript::ProcessCommands100To199(int32 command) ped->SetWanderPath(path); return 0; } - /* Not implemented. - case COMMAND_CHAR_WANDER_RANGE: - */ + //case COMMAND_CHAR_WANDER_RANGE: case COMMAND_CHAR_FOLLOW_PATH: { - CollectParameters(&m_nIp, 4); + CollectParameters(&m_nIp, 6); CPed* ped = CPools::GetPedPool()->GetAt(ScriptParams[0]); assert(ped); + if (ped->GetPedState() == PED_ATTACK || ped->GetPedState() == PED_FIGHT || !ped->IsPedInControl()) + return 0; CVector pos = *(CVector*)&ScriptParams[1]; if (pos.z <= MAP_Z_LOW_LIMIT) pos.z = CWorld::FindGroundZForCoord(pos.x, pos.y); + float radius = *(float*)&ScriptParams[4]; + eMoveState state; + switch (ScriptParams[5]) { + case 0: state = PEDMOVE_WALK; break; + case 1: state = PEDMOVE_SPRINT; break; + default: assert(0); + } ped->ClearAll(); - ped->SetFollowPath(pos); + ped->SetFollowPath(pos, radius, state, nil, nil, 999999); return 0; } case COMMAND_CHAR_SET_IDLE: @@ -1963,44 +2000,27 @@ int8 CRunningScript::ProcessCommands100To199(int32 command) CVector pos = *(CVector*)&ScriptParams[1]; if (pos.z <= MAP_Z_LOW_LIMIT) pos.z = CWorld::FindGroundZForCoord(pos.x, pos.y); - /* The following block was once again written - * by someone not familiar with virtual functions. - * It doesn't require any ifs at all. - * To keep as close to original as possible, I'll keep it. - * Maybe there was more commented out/debug - * stuff, but I doubt it. - */ + // removed dumb stuff again if (!vehicle) { pos.z += ped->GetDistanceFromCentreOfMassToBaseOfModel(); ped->Teleport(pos); CTheScripts::ClearSpaceForMissionEntity(pos, ped); - } - else if (vehicle->IsBoat()) { - pos.z += vehicle->GetDistanceFromCentreOfMassToBaseOfModel(); - vehicle->Teleport(pos); - CTheScripts::ClearSpaceForMissionEntity(pos, vehicle); + for (int i = 0; i < ped->m_numNearPeds; i++) { + CPed* pNearPed = ped->m_nearPeds[i]; + if (pNearPed->m_leader == ped) { + pNearPed->Teleport(pos); + pNearPed->PositionPedOutOfCollision(); // TODO(MIAMI): this is PositionAnyPedOutOfCollision!!! + } + } } else { pos.z += vehicle->GetDistanceFromCentreOfMassToBaseOfModel(); vehicle->Teleport(pos); CTheScripts::ClearSpaceForMissionEntity(pos, vehicle); } - /* Short version of this command. - * - * CollectParameters(&m_nIp, 4); - * CPed* ped = CPools::GetPedPool()->GetAt(ScriptParams[0]); - * assert(ped); - * CEntity* entityToMove = ped->bInVehicle ? ped->m_pMyVehicle : ped; - * CVector pos = *(CVector*)&ScriptParams[1]; - * if (pos.z <= MAP_Z_LOW_LIMIT) - * pos.z = CWorld::FindGroundZForCoord(pos.x, pos.y); - * pos.z += entityToMove->GetDistanceFromCentreOfMassToBaseOfModel(); - * entityToMove->Teleport(pos); - * CTheScripts::ClearSpaceForMissionEntity(pos, entityToMove); - * - */ return 0; } + /* case COMMAND_IS_CHAR_STILL_ALIVE: { CollectParameters(&m_nIp, 1); @@ -2008,6 +2028,7 @@ int8 CRunningScript::ProcessCommands100To199(int32 command) UpdateCompareFlag(ped && ped->GetPedState() != PED_DEAD && ped->GetPedState() != PED_DIE); return 0; } + */ case COMMAND_IS_CHAR_IN_AREA_2D: { CollectParameters(&m_nIp, 6); @@ -2075,7 +2096,7 @@ int8 CRunningScript::ProcessCommands100To199(int32 command) boat->SetStatus(STATUS_ABANDONED); boat->bIsLocked = true; boat->AutoPilot.m_nCarMission = MISSION_NONE; - boat->AutoPilot.m_nTempAction = TEMPACT_NONE; /* Animation ID? */ + boat->AutoPilot.m_nTempAction = TEMPACT_NONE; boat->AutoPilot.m_nCruiseSpeed = boat->AutoPilot.m_fMaxTrafficSpeed = 20.0f; if (m_bIsMissionScript) boat->bIsStaticWaitingForCollision = true; @@ -2084,8 +2105,10 @@ int8 CRunningScript::ProcessCommands100To199(int32 command) } else { CVehicle* car; - if (!CModelInfo::IsBikeModel(ScriptParams[0])) - car = new CAutomobile(ScriptParams[0], MISSION_VEHICLE); + + // TODO(MIAMI) + //if (!CModelInfo::IsBikeModel(ScriptParams[0])) + car = new CAutomobile(ScriptParams[0], MISSION_VEHICLE); CVector pos = *(CVector*)&ScriptParams[1]; if (pos.z <= MAP_Z_LOW_LIMIT) pos.z = CWorld::FindGroundZForCoord(pos.x, pos.y); @@ -2096,7 +2119,7 @@ int8 CRunningScript::ProcessCommands100To199(int32 command) car->bIsLocked = true; CCarCtrl::JoinCarWithRoadSystem(car); car->AutoPilot.m_nCarMission = MISSION_NONE; - car->AutoPilot.m_nTempAction = TEMPACT_NONE; /* Animation ID? */ + car->AutoPilot.m_nTempAction = TEMPACT_NONE; car->AutoPilot.m_nDrivingStyle = DRIVINGSTYLE_STOP_FOR_CARS; car->AutoPilot.m_nCruiseSpeed = car->AutoPilot.m_fMaxTrafficSpeed = 9.0f; car->AutoPilot.m_nCurrentLane = car->AutoPilot.m_nNextLane = 0; @@ -2226,6 +2249,7 @@ int8 CRunningScript::ProcessCommands100To199(int32 command) } return 0; } + /* case COMMAND_IS_CAR_STILL_ALIVE: { CollectParameters(&m_nIp, 1); @@ -2233,6 +2257,7 @@ int8 CRunningScript::ProcessCommands100To199(int32 command) UpdateCompareFlag(car && car->GetStatus() != STATUS_WRECKED && (car->IsBoat() || !car->bIsInWater)); return 0; } + */ case COMMAND_SET_CAR_CRUISE_SPEED: { CollectParameters(&m_nIp, 2); @@ -2307,32 +2332,28 @@ int8 CRunningScript::ProcessCommands100To199(int32 command) return 0; case COMMAND_PRINT_BIG: { - wchar* key = TheText.Get((char*)&CTheScripts::ScriptSpace[m_nIp]); - m_nIp += KEY_LENGTH_IN_SCRIPT; + wchar* key = CTheScripts::GetTextByKeyFromScript(&m_nIp); CollectParameters(&m_nIp, 2); CMessages::AddBigMessage(key, ScriptParams[0], ScriptParams[1] - 1); return 0; } case COMMAND_PRINT: { - wchar* key = TheText.Get((char*)&CTheScripts::ScriptSpace[m_nIp]); - m_nIp += KEY_LENGTH_IN_SCRIPT; + wchar* key = CTheScripts::GetTextByKeyFromScript(&m_nIp); CollectParameters(&m_nIp, 2); CMessages::AddMessage(key, ScriptParams[0], ScriptParams[1]); return 0; } case COMMAND_PRINT_NOW: { - wchar* key = TheText.Get((char*)&CTheScripts::ScriptSpace[m_nIp]); - m_nIp += KEY_LENGTH_IN_SCRIPT; + wchar* key = CTheScripts::GetTextByKeyFromScript(&m_nIp); CollectParameters(&m_nIp, 2); CMessages::AddMessageJumpQ(key, ScriptParams[0], ScriptParams[1]); return 0; } case COMMAND_PRINT_SOON: { - wchar* key = TheText.Get((char*)&CTheScripts::ScriptSpace[m_nIp]); - m_nIp += KEY_LENGTH_IN_SCRIPT; + wchar* key = CTheScripts::GetTextByKeyFromScript(&m_nIp); CollectParameters(&m_nIp, 2); CMessages::AddMessageSoon(key, ScriptParams[0], ScriptParams[1]); return 0; @@ -2369,15 +2390,15 @@ int8 CRunningScript::ProcessCommands100To199(int32 command) case COMMAND_DEBUG_OFF: CTheScripts::DbgFlag = false; return 0; + /* case COMMAND_RETURN_TRUE: UpdateCompareFlag(true); return 0; case COMMAND_RETURN_FALSE: UpdateCompareFlag(false); return 0; - /* Special command only used by compiler. - case COMMAND_VAR_INT: */ + //case COMMAND_VAR_INT: default: assert(0); break; @@ -2430,8 +2451,6 @@ int8 CRunningScript::ProcessCommands200To299(int32 command) { if (!m_bIsMissionScript) return 0; - if (strcmp(m_abScriptName, "love3") == 0) /* A Drop in the Ocean */ - CPickups::RemoveAllFloatingPickups(); CTheScripts::MissionCleanup.Process(); return 0; } @@ -2574,29 +2593,23 @@ int8 CRunningScript::ProcessCommands200To299(int32 command) { CollectParameters(&m_nIp, 1); CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]); - UpdateCompareFlag(pPed->bInVehicle); + UpdateCompareFlag(pPed->bInVehicle && pPed->m_pMyVehicle); return 0; } case COMMAND_IS_PLAYER_IN_ANY_CAR: { CollectParameters(&m_nIp, 1); CPed* pPed = CWorld::Players[ScriptParams[0]].m_pPed; - UpdateCompareFlag(pPed->bInVehicle); + UpdateCompareFlag(pPed->bInVehicle && pPed->m_pMyVehicle); return 0; } case COMMAND_IS_BUTTON_PRESSED: { CollectParameters(&m_nIp, 2); - bool value = GetPadState(ScriptParams[0], ScriptParams[1]) != 0; - if (CGame::playingIntro && ScriptParams[0] == 0 && ScriptParams[1] == 12) { - if (CPad::GetPad(0)->GetLeftMouseJustDown() || - CPad::GetPad(0)->GetEnterJustDown() || - CPad::GetPad(0)->GetCharJustDown(' ')) - value = true; - } - UpdateCompareFlag(value); + UpdateCompareFlag(GetPadState(ScriptParams[0], ScriptParams[1]) != 0); return 0; } + /* case COMMAND_GET_PAD_STATE: { CollectParameters(&m_nIp, 1); @@ -2604,6 +2617,7 @@ int8 CRunningScript::ProcessCommands200To299(int32 command) StoreParameters(&m_nIp, 1); return 0; } + */ case COMMAND_LOCATE_PLAYER_ANY_MEANS_2D: case COMMAND_LOCATE_PLAYER_ON_FOOT_2D: case COMMAND_LOCATE_PLAYER_IN_CAR_2D: @@ -2670,6 +2684,9 @@ int8 CRunningScript::ProcessCommands200To299(int32 command) pObj->SetOrientation(0.0f, 0.0f, 0.0f); pObj->GetMatrix().UpdateRW(); pObj->UpdateRwFrame(); + CBaseModelInfo* pModelInfo = CModelInfo::GetModelInfo(mi); + if (pModelInfo->IsBuilding() && ((CSimpleModelInfo*)pModelInfo)->m_isBigBuilding) + pObj->SetupBigBuilding(); CTheScripts::ClearSpaceForMissionEntity(pos, pObj); CWorld::Add(pObj); ScriptParams[0] = CPools::GetObjectPool()->GetIndex(pObj); @@ -2694,6 +2711,8 @@ int8 CRunningScript::ProcessCommands200To299(int32 command) case COMMAND_ADD_SCORE: CollectParameters(&m_nIp, 2); CWorld::Players[ScriptParams[0]].m_nMoney += ScriptParams[1]; + if (CWorld::Players[ScriptParams[0]].m_nMoney < 0) + CWorld::Players[ScriptParams[0]].m_nMoney = 0; return 0; case COMMAND_IS_SCORE_GREATER: CollectParameters(&m_nIp, 2); @@ -2736,12 +2755,14 @@ int8 CRunningScript::ProcessCommands200To299(int32 command) case COMMAND_HAS_DEATHARREST_BEEN_EXECUTED: UpdateCompareFlag(m_bDeatharrestExecuted); return 0; + /* case COMMAND_ADD_AMMO_TO_PLAYER: { CollectParameters(&m_nIp, 3); CWorld::Players[ScriptParams[0]].m_pPed->GrantAmmo((eWeaponType)ScriptParams[1], ScriptParams[2]); return 0; } + */ case COMMAND_ADD_AMMO_TO_CHAR: { CollectParameters(&m_nIp, 3); @@ -2750,10 +2771,8 @@ int8 CRunningScript::ProcessCommands200To299(int32 command) pPed->GrantAmmo((eWeaponType)ScriptParams[1], ScriptParams[2]); return 0; } - /* Not implemented - case COMMAND_ADD_AMMO_TO_CAR: - case COMMAND_IS_PLAYER_STILL_ALIVE: - */ + //case COMMAND_ADD_AMMO_TO_CAR: + //case COMMAND_IS_PLAYER_STILL_ALIVE: case COMMAND_IS_PLAYER_DEAD: CollectParameters(&m_nIp, 1); UpdateCompareFlag(CWorld::Players[ScriptParams[0]].m_WBState == WBSTATE_WASTED); @@ -2762,14 +2781,14 @@ int8 CRunningScript::ProcessCommands200To299(int32 command) { CollectParameters(&m_nIp, 1); CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]); - UpdateCompareFlag(!pPed || pPed->GetPedState() == PED_DIE || pPed->GetPedState() == PED_DEAD); + UpdateCompareFlag(!pPed || pPed->DyingOrDead()); return 0; } case COMMAND_IS_CAR_DEAD: { CollectParameters(&m_nIp, 1); CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]); - UpdateCompareFlag(!pVehicle || pVehicle->GetStatus() == STATUS_WRECKED || !pVehicle->IsBoat() && pVehicle->bIsInWater); + UpdateCompareFlag(!pVehicle || pVehicle->GetStatus() == STATUS_WRECKED || pVehicle->bIsDrowning); return 0; } case COMMAND_SET_CHAR_THREAT_SEARCH: @@ -2780,9 +2799,7 @@ int8 CRunningScript::ProcessCommands200To299(int32 command) pPed->m_fearFlags |= ScriptParams[1]; return 0; } - /* Not implemented. - case COMMAND_SET_CHAR_THREAT_REACTION: - */ + //case COMMAND_SET_CHAR_THREAT_REACTION: case COMMAND_SET_CHAR_OBJ_NO_OBJ: { CollectParameters(&m_nIp, 1); @@ -2792,12 +2809,10 @@ int8 CRunningScript::ProcessCommands200To299(int32 command) pPed->ClearObjective(); return 0; } - /* Not implemented. - case COMMAND_ORDER_DRIVER_OUT_OF_CAR: - case COMMAND_ORDER_CHAR_TO_DRIVE_CAR: - case COMMAND_ADD_PATROL_POINT: - case COMMAND_IS_PLAYER_IN_GANGZONE: - */ + //case COMMAND_ORDER_DRIVER_OUT_OF_CAR: + //case COMMAND_ORDER_CHAR_TO_DRIVE_CAR: + //case COMMAND_ADD_PATROL_POINT: + //case COMMAND_IS_PLAYER_IN_GANGZONE: case COMMAND_IS_PLAYER_IN_ZONE: { CollectParameters(&m_nIp, 1); @@ -2816,8 +2831,6 @@ int8 CRunningScript::ProcessCommands200To299(int32 command) CollectParameters(&m_nIp, 1); UpdateCompareFlag(CWorld::Players[ScriptParams[0]].m_pPed->GetPedState() == PED_DRIVING && CPad::GetPad(ScriptParams[0])->GetHorn()); - /* Is it correct that same parameter is used both as index of Players */ - /* and as ID of pad? Pratically this parameter is always 0 anyway of course. */ return 0; case COMMAND_HAS_CHAR_SPOTTED_PLAYER: { @@ -2827,10 +2840,8 @@ int8 CRunningScript::ProcessCommands200To299(int32 command) UpdateCompareFlag(pPed->OurPedCanSeeThisOne(CWorld::Players[ScriptParams[1]].m_pPed)); return 0; } - /* Not implemented. - case COMMAND_ORDER_CHAR_TO_BACKDOOR: - case COMMAND_ADD_CHAR_TO_GANG: - */ + //case COMMAND_ORDER_CHAR_TO_BACKDOOR: + //case COMMAND_ADD_CHAR_TO_GANG: case COMMAND_IS_CHAR_OBJECTIVE_PASSED: { CollectParameters(&m_nIp, 1); @@ -2886,6 +2897,9 @@ int8 CRunningScript::ProcessCommands200To299(int32 command) pPed->CharCreatedBy = MISSION_CHAR; pPed->bRespondsToThreats = false; pPed->bAllowMedicsToReviveMe = false; + pPed->bIsPlayerFriend = false; + if (pVehicle->bIsBus) + pPed->bRenderPedInCar = false; pPed->SetPosition(pVehicle->GetPosition()); pPed->SetOrientation(0.0f, 0.0f, 0.0f); pPed->SetPedState(PED_DRIVING); @@ -2901,13 +2915,7 @@ int8 CRunningScript::ProcessCommands200To299(int32 command) pVehicle->AutoPilot.m_nCarMission = MISSION_CRUISE; pVehicle->bEngineOn = true; pPed->bUsesCollision = false; -#ifdef FIX_BUGS - AnimationId anim = pVehicle->GetDriverAnim(); -#else - AnimationId anim = pVehicle->bLowVehicle ? ANIM_CAR_LSIT : ANIM_CAR_SIT; -#endif - pPed->m_pVehicleAnim = CAnimManager::BlendAnimation(pPed->GetClump(), ASSOCGRP_STD, anim, 100.0f); - pPed->StopNonPartialAnims(); + pPed->AddInCarAnims(pVehicle, true); pPed->m_nZoneLevel = CTheZones::GetLevelFromPosition(&pPed->GetPosition()); CWorld::Add(pPed); ScriptParams[0] = CPools::GetPedPool()->GetIndex(pPed); @@ -2941,7 +2949,7 @@ int8 CRunningScript::ProcessCommands200To299(int32 command) pPlayer->m_pPed->SetPedState(PED_IDLE); pPlayer->m_pPed->bUsesCollision = true; pPlayer->m_pPed->SetMoveSpeed(0.0f, 0.0f, 0.0f); - pPlayer->m_pPed->AddWeaponModel(CWeaponInfo::GetWeaponInfo(pPlayer->m_pPed->GetWeapon()->m_eWeaponType)->m_nModelId); + pPlayer->m_pPed->ReplaceWeaponWhenExitingVehicle(); pPlayer->m_pPed->RemoveInCarAnims(); if (pPlayer->m_pPed->m_pVehicleAnim) pPlayer->m_pPed->m_pVehicleAnim->blendDelta = -1000.0f; @@ -2955,9 +2963,7 @@ int8 CRunningScript::ProcessCommands200To299(int32 command) CTheScripts::ClearSpaceForMissionEntity(pos, pPlayer->m_pPed); return 0; } - /* Not implemented. - case COMMAND_MAKE_CHAR_DO_NOTHING: - */ + //case COMMAND_MAKE_CHAR_DO_NOTHING: default: assert(0); break; @@ -2968,22 +2974,21 @@ int8 CRunningScript::ProcessCommands200To299(int32 command) int8 CRunningScript::ProcessCommands300To399(int32 command) { switch (command) { - /* Not implemented. - case COMMAND_SET_CHAR_INVINCIBLE: - case COMMAND_SET_PLAYER_INVINCIBLE: - case COMMAND_SET_CHAR_GRAPHIC_TYPE: - case COMMAND_SET_PLAYER_GRAPHIC_TYPE: - */ + //case COMMAND_SET_CHAR_INVINCIBLE: + //case COMMAND_SET_PLAYER_INVINCIBLE: + //case COMMAND_SET_CHAR_GRAPHIC_TYPE: + //case COMMAND_SET_PLAYER_GRAPHIC_TYPE: + /* case COMMAND_HAS_PLAYER_BEEN_ARRESTED: CollectParameters(&m_nIp, 1); UpdateCompareFlag(CWorld::Players[ScriptParams[0]].m_WBState == WBSTATE_BUSTED); return 0; - /* Not implemented. - case COMMAND_STOP_CHAR_DRIVING: - case COMMAND_KILL_CHAR: - case COMMAND_SET_FAVOURITE_CAR_MODEL_FOR_CHAR: - case COMMAND_SET_CHAR_OCCUPATION: */ + //case COMMAND_STOP_CHAR_DRIVING: + //case COMMAND_KILL_CHAR: + //case COMMAND_SET_FAVOURITE_CAR_MODEL_FOR_CHAR: + //case COMMAND_SET_CHAR_OCCUPATION: + /* case COMMAND_CHANGE_CAR_LOCK: { CollectParameters(&m_nIp, 2); @@ -2999,6 +3004,7 @@ int8 CRunningScript::ProcessCommands300To399(int32 command) *(float*)&ScriptParams[2], *(float*)&ScriptParams[3]); return 0; + */ case COMMAND_IS_CAR_MODEL: { CollectParameters(&m_nIp, 2); @@ -3007,11 +3013,10 @@ int8 CRunningScript::ProcessCommands300To399(int32 command) UpdateCompareFlag(pVehicle->GetModelIndex() == ScriptParams[1]); return 0; } - /* Not implemented. - case COMMAND_IS_CAR_REMAP: - case COMMAND_HAS_CAR_JUST_SUNK: - case COMMAND_SET_CAR_NO_COLLIDE: - */ + //case COMMAND_IS_CAR_REMAP: + //case COMMAND_HAS_CAR_JUST_SUNK: + //case COMMAND_SET_CAR_NO_COLLIDE: + /* case COMMAND_IS_CAR_DEAD_IN_AREA_2D: { CollectParameters(&m_nIp, 6); @@ -3050,35 +3055,39 @@ int8 CRunningScript::ProcessCommands300To399(int32 command) CTheScripts::DrawDebugCube(x1, y1, z1, x2, y2, z2); return 0; } - /* Not implemented. - case COMMAND_IS_TRAILER_ATTACHED: - case COMMAND_IS_CAR_ON_TRAILER: - case COMMAND_HAS_CAR_GOT_WEAPON: - case COMMAND_PARK: - case COMMAND_HAS_PARK_FINISHED: - case COMMAND_KILL_ALL_PASSENGERS: - case COMMAND_SET_CAR_BULLETPROOF: - case COMMAND_SET_CAR_FLAMEPROOF: - case COMMAND_SET_CAR_ROCKETPROOF: - case COMMAND_IS_CARBOMB_ACTIVE: - case COMMAND_GIVE_CAR_ALARM: - case COMMAND_PUT_CAR_ON_TRAILER: */ + //case COMMAND_IS_TRAILER_ATTACHED: + //case COMMAND_IS_CAR_ON_TRAILER: + //case COMMAND_HAS_CAR_GOT_WEAPON: + //case COMMAND_PARK: + //case COMMAND_HAS_PARK_FINISHED: + //case COMMAND_KILL_ALL_PASSENGERS: + //case COMMAND_SET_CAR_BULLETPROOF: + //case COMMAND_SET_CAR_FLAMEPROOF: + //case COMMAND_SET_CAR_ROCKETPROOF: + //case COMMAND_IS_CARBOMB_ACTIVE: + //case COMMAND_GIVE_CAR_ALARM: + //case COMMAND_PUT_CAR_ON_TRAILER: + /* case COMMAND_IS_CAR_CRUSHED: CollectParameters(&m_nIp, 1); UpdateCompareFlag(CGarages::HasCarBeenCrushed(ScriptParams[0])); return 0; - /* Not implemented. - case COMMAND_CREATE_GANG_CAR: */ + //case COMMAND_CREATE_GANG_CAR: case COMMAND_CREATE_CAR_GENERATOR: + { CollectParameters(&m_nIp, 12); + CVector pos = *(CVector*)&ScriptParams[0]; + if (pos.z > MAP_Z_LOW_LIMIT) + pos.z += 0.015f; ScriptParams[0] = CTheCarGenerators::CreateCarGenerator( - *(float*)&ScriptParams[0], *(float*)&ScriptParams[1], *(float*)&ScriptParams[2], *(float*)&ScriptParams[3], + pos.x, pos.y, pos.z, *(float*)&ScriptParams[3], ScriptParams[4], ScriptParams[5], ScriptParams[6], ScriptParams[7], ScriptParams[8], ScriptParams[9], ScriptParams[10], ScriptParams[11]); StoreParameters(&m_nIp, 1); return 0; + } case COMMAND_SWITCH_CAR_GENERATOR: { CollectParameters(&m_nIp, 2); @@ -3087,12 +3096,13 @@ int8 CRunningScript::ProcessCommands300To399(int32 command) pCarGen->SwitchOff(); }else if (ScriptParams[1] <= 100){ pCarGen->SwitchOn(); + pCarGen->SetUsesRemaining(ScriptParams[1]); }else{ pCarGen->SwitchOn(); - pCarGen->SetUsesRemaining(ScriptParams[1]); } return 0; } + /* case COMMAND_ADD_PAGER_MESSAGE: { wchar* text = CTheScripts::GetTextByKeyFromScript(&m_nIp); @@ -3100,11 +3110,14 @@ int8 CRunningScript::ProcessCommands300To399(int32 command) CUserDisplay::Pager.AddMessage(text, ScriptParams[0], ScriptParams[1], ScriptParams[2]); return 0; } + */ case COMMAND_DISPLAY_ONSCREEN_TIMER: { assert(CTheScripts::ScriptSpace[m_nIp] == ARGUMENT_GLOBALVAR); m_nIp++; - CUserDisplay::OnscnTimer.AddClock(CTheScripts::Read2BytesFromScript(&m_nIp), nil); + uint32 offset = CTheScripts::Read2BytesFromScript(&m_nIp); + CollectParameters(&m_nIp, 1); + CUserDisplay::OnscnTimer.AddClock(offset, nil, ScriptParams[0] != 0); return 0; } case COMMAND_CLEAR_ONSCREEN_TIMER: @@ -3120,7 +3133,7 @@ int8 CRunningScript::ProcessCommands300To399(int32 command) m_nIp++; int32 counter = CTheScripts::Read2BytesFromScript(&m_nIp); CollectParameters(&m_nIp, 1); - CUserDisplay::OnscnTimer.AddCounter(counter, ScriptParams[0], nil); + CUserDisplay::OnscnTimer.AddCounter(counter, ScriptParams[0], nil, 0); return 0; } case COMMAND_CLEAR_ONSCREEN_COUNTER: @@ -3156,9 +3169,7 @@ int8 CRunningScript::ProcessCommands300To399(int32 command) } return 0; } - /* Not implemented. - case COMMAND_IS_CHAR_IN_GANG_ZONE: - */ + //case COMMAND_IS_CHAR_IN_GANG_ZONE: case COMMAND_IS_CHAR_IN_ZONE: { CollectParameters(&m_nIp, 1); @@ -3173,10 +3184,8 @@ int8 CRunningScript::ProcessCommands300To399(int32 command) UpdateCompareFlag(CTheZones::PointLiesWithinZone(&pos, CTheZones::GetNavigationZone(zone))); return 0; } - /* Not implemented. - case COMMAND_SET_CAR_DENSITY: - case COMMAND_SET_PED_DENSITY: - */ + //case COMMAND_SET_CAR_DENSITY: + //case COMMAND_SET_PED_DENSITY: case COMMAND_POINT_CAMERA_AT_PLAYER: { CollectParameters(&m_nIp, 3); @@ -3188,24 +3197,26 @@ int8 CRunningScript::ProcessCommands300To399(int32 command) { CollectParameters(&m_nIp, 3); CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]); - assert(pVehicle); - TheCamera.TakeControl(pVehicle, ScriptParams[1], ScriptParams[2], CAMCONTROL_SCRIPT); + if (pVehicle) + TheCamera.TakeControl(pVehicle, ScriptParams[1], ScriptParams[2], CAMCONTROL_SCRIPT); return 0; } case COMMAND_POINT_CAMERA_AT_CHAR: { CollectParameters(&m_nIp, 3); CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]); - assert(pPed); - TheCamera.TakeControl(pPed, ScriptParams[1], ScriptParams[2], CAMCONTROL_SCRIPT); + if (pPed) + TheCamera.TakeControl(pPed, ScriptParams[1], ScriptParams[2], CAMCONTROL_SCRIPT); return 0; } case COMMAND_RESTORE_CAMERA: TheCamera.Restore(); return 0; + /* case COMMAND_SHAKE_PAD: CPad::GetPad(ScriptParams[0])->StartShake(ScriptParams[1], ScriptParams[2]); return 0; + */ case COMMAND_SET_ZONE_PED_INFO: { char label[12]; @@ -3228,6 +3239,7 @@ int8 CRunningScript::ProcessCommands300To399(int32 command) CollectParameters(&m_nIp, 1); CTimer::SetTimeScale(*(float*)&ScriptParams[0]); return 0; + /* case COMMAND_IS_CAR_IN_AIR: { CollectParameters(&m_nIp, 1); @@ -3237,6 +3249,7 @@ int8 CRunningScript::ProcessCommands300To399(int32 command) UpdateCompareFlag(pCar->GetAllWheelsOffGround()); return 0; } + */ case COMMAND_SET_FIXED_CAMERA_POSITION: { CollectParameters(&m_nIp, 6); @@ -3259,7 +3272,6 @@ int8 CRunningScript::ProcessCommands300To399(int32 command) CollectParameters(&m_nIp, 3); CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]); assert(pVehicle); - // Useless call. CRadar::GetActualBlipArrayIndex(CollectNextParameterWithoutIncreasingPC(m_nIp)); ScriptParams[0] = CRadar::SetEntityBlip(BLIP_CAR, ScriptParams[0], ScriptParams[1], (eBlipDisplay)ScriptParams[2]); StoreParameters(&m_nIp, 1); @@ -3270,23 +3282,23 @@ int8 CRunningScript::ProcessCommands300To399(int32 command) CollectParameters(&m_nIp, 3); CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]); assert(pPed); - // Useless call. CRadar::GetActualBlipArrayIndex(CollectNextParameterWithoutIncreasingPC(m_nIp)); ScriptParams[0] = CRadar::SetEntityBlip(BLIP_CHAR, ScriptParams[0], ScriptParams[1], (eBlipDisplay)ScriptParams[2]); StoreParameters(&m_nIp, 1); return 0; } + /* case COMMAND_ADD_BLIP_FOR_OBJECT_OLD: { CollectParameters(&m_nIp, 3); CObject* pObject = CPools::GetObjectPool()->GetAt(ScriptParams[0]); assert(pObject); - // Useless call. CRadar::GetActualBlipArrayIndex(CollectNextParameterWithoutIncreasingPC(m_nIp)); ScriptParams[0] = CRadar::SetEntityBlip(BLIP_OBJECT, ScriptParams[0], ScriptParams[1], (eBlipDisplay)ScriptParams[2]); StoreParameters(&m_nIp, 1); return 0; } + */ case COMMAND_REMOVE_BLIP: CollectParameters(&m_nIp, 1); CRadar::ClearBlip(ScriptParams[0]); @@ -3305,7 +3317,6 @@ int8 CRunningScript::ProcessCommands300To399(int32 command) CVector pos = *(CVector*)&ScriptParams[0]; if (pos.z <= MAP_Z_LOW_LIMIT) pos.z = CWorld::FindGroundZForCoord(pos.x, pos.y); - // Useless call CRadar::GetActualBlipArrayIndex(CollectNextParameterWithoutIncreasingPC(m_nIp)); ScriptParams[0] = CRadar::SetCoordBlip(BLIP_COORD, pos, ScriptParams[3], (eBlipDisplay)ScriptParams[4]); StoreParameters(&m_nIp, 1); @@ -3356,6 +3367,7 @@ int8 CRunningScript::ProcessCommands300To399(int32 command) CRestart::OverrideNextRestart(pos, angle); return 0; } + /* case COMMAND_DRAW_SHADOW: { CollectParameters(&m_nIp, 10); @@ -3374,11 +3386,11 @@ int8 CRunningScript::ProcessCommands300To399(int32 command) float frontY = y; float sideX = y; float sideY = x; - /* Not very nicely named intermediate variables. */ CShadows::StoreShadowToBeRendered(ScriptParams[0], &pos, frontX, frontY, sideX, sideY, ScriptParams[6], ScriptParams[7], ScriptParams[8], ScriptParams[9]); return 0; } + */ case COMMAND_GET_PLAYER_HEADING: { CollectParameters(&m_nIp, 1); @@ -3392,10 +3404,9 @@ int8 CRunningScript::ProcessCommands300To399(int32 command) { CollectParameters(&m_nIp, 2); CPed* pPed = CWorld::Players[ScriptParams[0]].m_pPed; - if (pPed->bInVehicle){ - // Is assertion required? + assert(pPed); + if (pPed->bInVehicle) return 0; - } pPed->m_fRotationDest = pPed->m_fRotationCur = DEGTORAD(*(float*)&ScriptParams[1]); pPed->SetHeading(DEGTORAD(*(float*)&ScriptParams[1])); return 0; @@ -3415,10 +3426,8 @@ int8 CRunningScript::ProcessCommands300To399(int32 command) CollectParameters(&m_nIp, 2); CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]); assert(pPed); - if (pPed->bInVehicle) { - // Is assertion required? + if (pPed->bInVehicle) return 0; - } pPed->m_fRotationDest = pPed->m_fRotationCur = DEGTORAD(*(float*)&ScriptParams[1]); pPed->SetHeading(DEGTORAD(*(float*)&ScriptParams[1])); return 0; @@ -3463,6 +3472,7 @@ int8 CRunningScript::ProcessCommands300To399(int32 command) CWorld::Add(pObject); return 0; } + /* case COMMAND_IS_PLAYER_TOUCHING_OBJECT: { CollectParameters(&m_nIp, 2); @@ -3484,12 +3494,14 @@ int8 CRunningScript::ProcessCommands300To399(int32 command) UpdateCompareFlag(pEntityToTest->GetHasCollidedWith(pObject)); return 0; } + */ case COMMAND_SET_PLAYER_AMMO: { CollectParameters(&m_nIp, 3); CWorld::Players[0].m_pPed->SetAmmo((eWeaponType)ScriptParams[1], ScriptParams[2]); return 0; } + /* case COMMAND_SET_CHAR_AMMO: { CollectParameters(&m_nIp, 3); @@ -3497,23 +3509,17 @@ int8 CRunningScript::ProcessCommands300To399(int32 command) pPed->SetAmmo((eWeaponType)ScriptParams[1], ScriptParams[2]); return 0; } - /* Not implemented. - case COMMAND_SET_CAR_AMMO: - case COMMAND_LOAD_CAMERA_SPLINE: - case COMMAND_MOVE_CAMERA_ALONG_SPLINE: - case COMMAND_GET_CAMERA_POSITION_ALONG_SPLINE: */ + //case COMMAND_SET_CAR_AMMO: + //case COMMAND_LOAD_CAMERA_SPLINE: + //case COMMAND_MOVE_CAMERA_ALONG_SPLINE: + //case COMMAND_GET_CAMERA_POSITION_ALONG_SPLINE: case COMMAND_DECLARE_MISSION_FLAG: CTheScripts::OnAMissionFlag = CTheScripts::Read2BytesFromScript(&++m_nIp); return 0; case COMMAND_DECLARE_MISSION_FLAG_FOR_CONTACT: - CollectParameters(&m_nIp, 1); - CTheScripts::OnAMissionForContactFlag[ScriptParams[0]] = CTheScripts::Read2BytesFromScript(&++m_nIp); - return 0; - case COMMAND_DECLARE_BASE_BRIEF_ID_FOR_CONTACT: - CollectParameters(&m_nIp, 2); - CTheScripts::BaseBriefIdForContact[ScriptParams[0]] = ScriptParams[1]; return 0; + //case COMMAND_DECLARE_BASE_BRIEF_ID_FOR_CONTACT: case COMMAND_IS_PLAYER_HEALTH_GREATER: { CollectParameters(&m_nIp, 2); @@ -3542,7 +3548,6 @@ int8 CRunningScript::ProcessCommands300To399(int32 command) CollectParameters(&m_nIp, 1); CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]); assert(pVehicle); - // Useless call. CRadar::GetActualBlipArrayIndex(CollectNextParameterWithoutIncreasingPC(m_nIp)); int handle = CRadar::SetEntityBlip(BLIP_CAR, ScriptParams[0], 0, BLIP_DISPLAY_BOTH); CRadar::ChangeBlipScale(handle, 3); @@ -3555,7 +3560,6 @@ int8 CRunningScript::ProcessCommands300To399(int32 command) CollectParameters(&m_nIp, 1); CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]); assert(pPed); - // Useless call. CRadar::GetActualBlipArrayIndex(CollectNextParameterWithoutIncreasingPC(m_nIp)); int handle = CRadar::SetEntityBlip(BLIP_CHAR, ScriptParams[0], 1, BLIP_DISPLAY_BOTH); CRadar::ChangeBlipScale(handle, 3); @@ -3568,7 +3572,6 @@ int8 CRunningScript::ProcessCommands300To399(int32 command) CollectParameters(&m_nIp, 1); CObject* pObject = CPools::GetObjectPool()->GetAt(ScriptParams[0]); assert(pObject); - // Useless call. CRadar::GetActualBlipArrayIndex(CollectNextParameterWithoutIncreasingPC(m_nIp)); int handle = CRadar::SetEntityBlip(BLIP_OBJECT, ScriptParams[0], 6, BLIP_DISPLAY_BOTH); CRadar::ChangeBlipScale(handle, 3); @@ -3582,7 +3585,6 @@ int8 CRunningScript::ProcessCommands300To399(int32 command) CVector pos = *(CVector*)&ScriptParams[0]; if (pos.z <= MAP_Z_LOW_LIMIT) pos.z = CWorld::FindGroundZForCoord(pos.x, pos.y); - // Useless call CRadar::GetActualBlipArrayIndex(CollectNextParameterWithoutIncreasingPC(m_nIp)); int handle = CRadar::SetCoordBlip(BLIP_COORD, pos, 2, BLIP_DISPLAY_BOTH); CRadar::ChangeBlipScale(handle, 3); @@ -3596,7 +3598,6 @@ int8 CRunningScript::ProcessCommands300To399(int32 command) CVector pos = *(CVector*)&ScriptParams[0]; if (pos.z <= MAP_Z_LOW_LIMIT) pos.z = CWorld::FindGroundZForCoord(pos.x, pos.y); - // Useless call CRadar::GetActualBlipArrayIndex(CollectNextParameterWithoutIncreasingPC(m_nIp)); int handle = CRadar::SetCoordBlip(BLIP_COORD, pos, 5, BLIP_DISPLAY_BOTH); CRadar::ChangeBlipScale(handle, 3); @@ -3611,6 +3612,15 @@ int8 CRunningScript::ProcessCommands300To399(int32 command) case COMMAND_ADD_ONE_OFF_SOUND: { CollectParameters(&m_nIp, 4); + // TODO(MIAMI) + // SOUND_PART_MISSION_COMPLETE == 1 + // SOUND_RACE_START_3 == 7 + // SOUND_RACE_START_2 == 8 + // SOUND_RACE_START_1 == 9 + // SOUND_RACE_START_GO == 10 + // SOUND_AMMUNATION_BUY_WEAPON == 13 + // SOUND_AMMUNATION_BUY_WEAPON_DENIED == 14 + // SOUND_AMMUNATION_IMRAN_ARM_BOMB == 16 switch (ScriptParams[3]) { case SCRIPT_SOUND_EVIDENCE_PICKUP: DMAudio.PlayFrontEndSound(SOUND_EVIDENCE_PICKUP, 0); @@ -3636,11 +3646,8 @@ int8 CRunningScript::ProcessCommands300To399(int32 command) default: break; } -#ifdef FIX_BUGS - /* BUG: if audio is not initialized, this object will not be freed. */ if (!DMAudio.IsAudioInitialised()) return 0; -#endif cAudioScriptObject* obj = new cAudioScriptObject(); obj->Posn = *(CVector*)&ScriptParams[0]; obj->AudioId = ScriptParams[3]; @@ -3651,11 +3658,15 @@ int8 CRunningScript::ProcessCommands300To399(int32 command) case COMMAND_ADD_CONTINUOUS_SOUND: { CollectParameters(&m_nIp, 4); - cAudioScriptObject* obj = new cAudioScriptObject(); - obj->Posn = *(CVector*)&ScriptParams[0]; - obj->AudioId = ScriptParams[3]; - obj->AudioEntity = DMAudio.CreateLoopingScriptObject(obj); - ScriptParams[0] = CPools::GetAudioScriptObjectPool()->GetIndex(obj); + if (DMAudio.IsAudioInitialised()) { + cAudioScriptObject* obj = new cAudioScriptObject(); + obj->Posn = *(CVector*)&ScriptParams[0]; + obj->AudioId = ScriptParams[3]; + obj->AudioEntity = DMAudio.CreateLoopingScriptObject(obj); + ScriptParams[0] = CPools::GetAudioScriptObjectPool()->GetIndex(obj); + } + else + ScriptParams[0] = -1; StoreParameters(&m_nIp, 1); return 0; } @@ -3734,6 +3745,7 @@ int8 CRunningScript::ProcessCommands400To499(int32 command) pPed->SetObjective(OBJECTIVE_GUARD_SPOT, pos); return 0; } + /* case COMMAND_SET_CHAR_OBJ_GUARD_AREA: { CollectParameters(&m_nIp, 5); @@ -3769,6 +3781,7 @@ int8 CRunningScript::ProcessCommands400To499(int32 command) pPed->SetObjective(OBJECTIVE_WAIT_IN_CAR); return 0; } + */ case COMMAND_IS_PLAYER_IN_AREA_ON_FOOT_2D: case COMMAND_IS_PLAYER_IN_AREA_IN_CAR_2D: case COMMAND_IS_PLAYER_STOPPED_IN_AREA_2D: @@ -3817,31 +3830,21 @@ int8 CRunningScript::ProcessCommands400To499(int32 command) CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]); assert(pPed); pPed->SetCurrentWeapon(pPed->GiveWeapon((eWeaponType)ScriptParams[1], ScriptParams[2])); - if (pPed->bInVehicle) + if (pPed->bInVehicle && pPed->m_pMyVehicle) pPed->RemoveWeaponModel(CWeaponInfo::GetWeaponInfo(pPed->m_weapons[pPed->m_currentWeapon].m_eWeaponType)->m_nModelId); return 0; } - /* Not implemented */ //case COMMAND_GIVE_WEAPON_TO_CAR: case COMMAND_SET_PLAYER_CONTROL: { CollectParameters(&m_nIp, 2); CPlayerInfo* pPlayer = &CWorld::Players[ScriptParams[0]]; if (ScriptParams[1]){ - if (CGame::playingIntro || CTheScripts::DelayMakingPlayerUnsafeThisTime){ - CTheScripts::CountdownToMakePlayerUnsafe = 50; - if (CTheScripts::DelayMakingPlayerUnsafeThisTime) - CTheScripts::DelayMakingPlayerUnsafeThisTime--; - }else{ - pPlayer->MakePlayerSafe(false); - } + pPlayer->MakePlayerSafe(false); + if (strcmp(m_abScriptName, "serg1") == 0) // Four Iron + pPlayer->m_pPed->ClearFollowPath(); }else{ pPlayer->MakePlayerSafe(true); - if (strcmp(m_abScriptName, "camera") == 0){ - pPlayer->m_pPed->SetMoveSpeed(0.0f, 0.0f, 0.0f); - pPlayer->m_pPed->SetTurnSpeed(0.0f, 0.0f, 0.0f); - CAnimManager::BlendAnimation((RpClump*)pPlayer->m_pPed->m_rwObject, pPlayer->m_pPed->m_animGroup, ANIM_IDLE_STANCE, 1000.0f); - } } return 0; } @@ -3876,7 +3879,6 @@ int8 CRunningScript::ProcessCommands400To499(int32 command) } return 0; } - /* Not implemented */ //case COMMAND_SET_CURRENT_CAR_WEAPON: case COMMAND_GET_OBJECT_COORDINATES: { @@ -4066,9 +4068,11 @@ int8 CRunningScript::ProcessCommands400To499(int32 command) pPed->CharCreatedBy = MISSION_CHAR; pPed->bRespondsToThreats = false; pPed->bAllowMedicsToReviveMe = false; + pPed->bIsPlayerFriend = false; + if (pVehicle->bIsBus) + pPed->bRenderPedInCar = false; pPed->SetPosition(pVehicle->GetPosition()); pPed->SetOrientation(0.0f, 0.0f, 0.0f); - pPed->SetPedState(PED_DRIVING); CPopulation::ms_nTotalMissionPeds++; if (ScriptParams[3] >= 0) pVehicle->AddPassenger(pPed, ScriptParams[3]); @@ -4077,16 +4081,10 @@ int8 CRunningScript::ProcessCommands400To499(int32 command) pPed->m_pMyVehicle = pVehicle; pPed->m_pMyVehicle->RegisterReference((CEntity**)&pPed->m_pMyVehicle); pPed->bInVehicle = true; - pPed->SetPedState(PED_DRIVING); pVehicle->SetStatus(STATUS_PHYSICS); + pPed->SetPedState(PED_DRIVING); pPed->bUsesCollision = false; -#ifdef FIX_BUGS - AnimationId anim = pVehicle->GetDriverAnim(); -#else - AnimationId anim = pVehicle->bLowVehicle ? ANIM_CAR_LSIT : ANIM_CAR_SIT; -#endif - pPed->m_pVehicleAnim = CAnimManager::BlendAnimation(pPed->GetClump(), ASSOCGRP_STD, anim, 100.0f); - pPed->StopNonPartialAnims(); + pPed->AddInCarAnims(pVehicle, false); pPed->m_nZoneLevel = CTheZones::GetLevelFromPosition(&pPed->GetPosition()); CWorld::Add(pPed); ScriptParams[0] = CPools::GetPedPool()->GetIndex(pPed); @@ -4135,6 +4133,7 @@ int8 CRunningScript::ProcessCommands400To499(int32 command) pPed->SetObjective(OBJECTIVE_KILL_CHAR_ANY_MEANS, pTarget); return 0; } + /* case COMMAND_SET_CHAR_OBJ_FLEE_CHAR_ON_FOOT_TILL_SAFE: { CollectParameters(&m_nIp, 2); @@ -4145,6 +4144,7 @@ int8 CRunningScript::ProcessCommands400To499(int32 command) pPed->SetObjective(OBJECTIVE_FLEE_CHAR_ON_FOOT_TILL_SAFE, pTarget); return 0; } + */ case COMMAND_SET_CHAR_OBJ_FLEE_PLAYER_ON_FOOT_TILL_SAFE: { CollectParameters(&m_nIp, 2); @@ -4225,11 +4225,18 @@ int8 CRunningScript::ProcessCommands400To499(int32 command) pPed->SetObjective(OBJECTIVE_ENTER_CAR_AS_DRIVER, pVehicle); return 0; } - /* Not implemented. - case COMMAND_SET_CHAR_OBJ_FOLLOW_CAR_IN_CAR: - case COMMAND_SET_CHAR_OBJ_FIRE_AT_OBJECT_FROM_VEHICLE: + //case COMMAND_SET_CHAR_OBJ_FOLLOW_CAR_IN_CAR: + //case COMMAND_SET_CHAR_OBJ_FIRE_AT_OBJECT_FROM_VEHICLE: case COMMAND_SET_CHAR_OBJ_DESTROY_OBJECT: - */ + { + CollectParameters(&m_nIp, 2); + CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]); + assert(pPed); + CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[1]); + pPed->bScriptObjectiveCompleted = false; + pPed->SetObjective(OBJECTIVE_DESTROY_OBJ, pVehicle); + return 0; + } case COMMAND_SET_CHAR_OBJ_DESTROY_CAR: { CollectParameters(&m_nIp, 2); @@ -4240,6 +4247,7 @@ int8 CRunningScript::ProcessCommands400To499(int32 command) pPed->SetObjective(OBJECTIVE_DESTROY_CAR, pVehicle); return 0; } + /* case COMMAND_SET_CHAR_OBJ_GOTO_AREA_ON_FOOT: { CollectParameters(&m_nIp, 5); @@ -4266,11 +4274,10 @@ int8 CRunningScript::ProcessCommands400To499(int32 command) pPed->SetObjective(OBJECTIVE_GOTO_AREA_ON_FOOT, pos, radius); return 0; } - /* Not implemented. - case COMMAND_SET_CHAR_OBJ_GOTO_AREA_IN_CAR: - case COMMAND_SET_CHAR_OBJ_FOLLOW_CAR_ON_FOOT_WITH_OFFSET: - case COMMAND_SET_CHAR_OBJ_GUARD_ATTACK: */ + //case COMMAND_SET_CHAR_OBJ_GOTO_AREA_IN_CAR: + //case COMMAND_SET_CHAR_OBJ_FOLLOW_CAR_ON_FOOT_WITH_OFFSET: + //case COMMAND_SET_CHAR_OBJ_GUARD_ATTACK: case COMMAND_SET_CHAR_AS_LEADER: { CollectParameters(&m_nIp, 2); @@ -4333,9 +4340,7 @@ int8 CRunningScript::ProcessCommands400To499(int32 command) CMessages::AddMessageJumpQWithNumber(text, ScriptParams[1], ScriptParams[2], ScriptParams[0], -1, -1, -1, -1, -1); return 0; } - /* Not implemented. - case COMMAND_PRINT_WITH_NUMBER_SOON: - */ + //case COMMAND_PRINT_WITH_NUMBER_SOON: case COMMAND_SWITCH_ROADS_ON: { CollectParameters(&m_nIp, 6); @@ -4410,10 +4415,19 @@ int8 CRunningScript::ProcessCommands400To499(int32 command) } case COMMAND_SET_CAR_HEAVY: { - CollectParameters(&m_nIp, 1); + CollectParameters(&m_nIp, 2); CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]); assert(pVehicle); - pVehicle->bIsHeavy = (ScriptParams[1] != 0); + if (ScriptParams[1] != 0) { + pVehicle->bIsHeavy = true; + pVehicle->m_fMass = 3.0f * pVehicle->pHandling->fMass; + pVehicle->m_fTurnMass = 5.0f * pVehicle->pHandling->fTurnMass; + } + else { + pVehicle->bIsHeavy = false; + pVehicle->m_fMass = pVehicle->pHandling->fMass; + pVehicle->m_fTurnMass = pVehicle->pHandling->fTurnMass; + } return 0; } case COMMAND_CLEAR_CHAR_THREAT_SEARCH: @@ -4424,6 +4438,7 @@ int8 CRunningScript::ProcessCommands400To499(int32 command) pPed->m_fearFlags = 0; return 0; } + /* case COMMAND_ACTIVATE_CRANE: { CollectParameters(&m_nIp, 10); @@ -4451,16 +4466,15 @@ int8 CRunningScript::ProcessCommands400To499(int32 command) CCranes::DeActivateCrane(*(float*)&ScriptParams[0], *(float*)&ScriptParams[1]); return 0; } + */ case COMMAND_SET_MAX_WANTED_LEVEL: { CollectParameters(&m_nIp, 1); CWanted::SetMaximumWantedLevel(ScriptParams[0]); return 0; } - /* Debug commands? - case COMMAND_SAVE_VAR_INT: - case COMMAND_SAVE_VAR_FLOAT: - */ + //case COMMAND_SAVE_VAR_INT: + //case COMMAND_SAVE_VAR_FLOAT: case COMMAND_IS_CAR_IN_AIR_PROPER: { CollectParameters(&m_nIp, 1); @@ -4512,6 +4526,7 @@ int8 CRunningScript::ProcessCommands500To599(int32 command) } return 0; } + /* case COMMAND_ADD_PAGER_MESSAGE_WITH_NUMBER: { wchar* text = CTheScripts::GetTextByKeyFromScript(&m_nIp); @@ -4520,6 +4535,7 @@ int8 CRunningScript::ProcessCommands500To599(int32 command) ScriptParams[1], ScriptParams[2], ScriptParams[3]); return 0; } + */ case COMMAND_START_KILL_FRENZY: { wchar* text = CTheScripts::GetTextByKeyFromScript(&m_nIp); @@ -4664,7 +4680,6 @@ int8 CRunningScript::ProcessCommands500To599(int32 command) pPed->SetObjective(OBJECTIVE_GOTO_AREA_ON_FOOT, target); return 0; } - /* Not implemented*/ //case COMMAND_SET_CHAR_OBJ_GOTO_COORD_IN_CAR: case COMMAND_CREATE_PICKUP: { @@ -4704,6 +4719,7 @@ int8 CRunningScript::ProcessCommands500To599(int32 command) CMessages::AddBigMessageQ(text, ScriptParams[0], ScriptParams[1] - 1); return 0; } + /* case COMMAND_PRINT_WITH_NUMBER_BIG_Q: { wchar* text = CTheScripts::GetTextByKeyFromScript(&m_nIp); @@ -4712,6 +4728,7 @@ int8 CRunningScript::ProcessCommands500To599(int32 command) ScriptParams[0], -1, -1, -1, -1, -1); return 0; } + */ case COMMAND_SET_GARAGE: { CollectParameters(&m_nIp, 9); @@ -4723,12 +4740,11 @@ int8 CRunningScript::ProcessCommands500To599(int32 command) float supX = *(float*)&ScriptParams[5]; float supY = *(float*)&ScriptParams[6]; float supZ = *(float*)&ScriptParams[7]; - - // TODO(MIAMI): new 2 parameters, requires CGarage change ScriptParams[0] = CGarages::AddOne(infX, infY, infZ, X2, Y2, supX, supY, supZ, (eGarageType)ScriptParams[8], 0); StoreParameters(&m_nIp, 1); return 0; } + /* case COMMAND_SET_GARAGE_WITH_CAR_MODEL: { CollectParameters(&m_nIp, 10); @@ -4740,11 +4756,11 @@ int8 CRunningScript::ProcessCommands500To599(int32 command) float supX = *(float*)&ScriptParams[5]; float supY = *(float*)&ScriptParams[6]; float supZ = *(float*)&ScriptParams[7]; - // TODO(MIAMI): new 2 parameters, requires CGarage change ScriptParams[0] = CGarages::AddOne(infX, infY, infZ, X2, Y2, supX, supY, supZ, (eGarageType)ScriptParams[8], ScriptParams[9]); StoreParameters(&m_nIp, 1); return 0; } + */ case COMMAND_SET_TARGET_CAR_FOR_MISSION_GARAGE: { CollectParameters(&m_nIp, 2); @@ -4802,6 +4818,7 @@ int8 CRunningScript::ProcessCommands500To599(int32 command) return 0; } #endif // GTA_PS2 + /* case COMMAND_SET_ALL_TAXI_LIGHTS: CollectParameters(&m_nIp, 1); CAutomobile::SetAllTaxiLights(ScriptParams[0] != 0); @@ -4815,6 +4832,7 @@ int8 CRunningScript::ProcessCommands500To599(int32 command) UpdateCompareFlag(pCar->m_bombType != 0); //TODO: enum return 0; } + */ case COMMAND_APPLY_BRAKES_TO_PLAYERS_CAR: CollectParameters(&m_nIp, 2); CPad::GetPad(ScriptParams[0])->bApplyBrakes = (ScriptParams[1] != 0); @@ -4824,7 +4842,7 @@ int8 CRunningScript::ProcessCommands500To599(int32 command) CollectParameters(&m_nIp, 2); CPlayerPed* pPed = CWorld::Players[ScriptParams[0]].m_pPed; assert(pPed); - pPed->m_fHealth = ScriptParams[1]; + pPed->m_fHealth = Min(ScriptParams[1], CWorld::Players[ScriptParams[0]].m_nMaxHealth); return 0; } case COMMAND_SET_CHAR_HEALTH: @@ -4858,7 +4876,7 @@ int8 CRunningScript::ProcessCommands500To599(int32 command) CollectParameters(&m_nIp, 1); CPed* pPed = CWorld::Players[ScriptParams[0]].m_pPed; assert(pPed); - ScriptParams[0] = pPed->m_fHealth; // correct cast float to int + ScriptParams[0] = pPed->m_fHealth; StoreParameters(&m_nIp, 1); return 0; } @@ -4867,7 +4885,7 @@ int8 CRunningScript::ProcessCommands500To599(int32 command) CollectParameters(&m_nIp, 1); CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]); assert(pPed); - ScriptParams[0] = pPed->m_fHealth; // correct cast float to int + ScriptParams[0] = pPed->m_fHealth; StoreParameters(&m_nIp, 1); return 0; } @@ -4876,19 +4894,21 @@ int8 CRunningScript::ProcessCommands500To599(int32 command) CollectParameters(&m_nIp, 1); CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]); assert(pVehicle); - ScriptParams[0] = pVehicle->m_fHealth; // correct cast float to int + ScriptParams[0] = pVehicle->m_fHealth; StoreParameters(&m_nIp, 1); return 0; } + /* case COMMAND_IS_CAR_ARMED_WITH_BOMB: { CollectParameters(&m_nIp, 2); CAutomobile* pCar = (CAutomobile*)CPools::GetVehiclePool()->GetAt(ScriptParams[0]); assert(pCar); assert(pCar->m_vehType == VEHICLE_TYPE_CAR); - UpdateCompareFlag(pCar->m_bombType == ScriptParams[1]); //TODO: enum + UpdateCompareFlag(pCar->m_bombType == ScriptParams[1]); return 0; } + */ case COMMAND_CHANGE_CAR_COLOUR: { CollectParameters(&m_nIp, 3); @@ -5002,15 +5022,19 @@ int8 CRunningScript::ProcessCommands500To599(int32 command) pSourcePed->RestorePreviousState(); return 0; } + /* case COMMAND_SWITCH_HELICOPTER: CollectParameters(&m_nIp, 1); CHeli::ActivateHeli(ScriptParams[0] != 0); return 0; - - //case COMMAND_SET_GANG_ATTITUDE: - //case COMMAND_SET_GANG_GANG_ATTITUDE: - //case COMMAND_SET_GANG_PLAYER_ATTITUDE: - //case COMMAND_SET_GANG_PED_MODELS: + */ + //case COMMAND_SET_GANG_ATTITUDE: + //case COMMAND_SET_GANG_GANG_ATTITUDE: + //case COMMAND_SET_GANG_PLAYER_ATTITUDE: + case COMMAND_SET_GANG_PED_MODELS: + CollectParameters(&m_nIp, 3); + CGangs::SetGangPedModels(ScriptParams[0], ScriptParams[1], ScriptParams[2]); + return 0; case COMMAND_SET_GANG_CAR_MODEL: CollectParameters(&m_nIp, 2); CGangs::SetGangVehicleModel(ScriptParams[0], ScriptParams[1]); @@ -5019,6 +5043,7 @@ int8 CRunningScript::ProcessCommands500To599(int32 command) CollectParameters(&m_nIp, 3); CGangs::SetGangWeapons(ScriptParams[0], (eWeaponType)ScriptParams[1], (eWeaponType)ScriptParams[2]); return 0; + /* case COMMAND_SET_CHAR_OBJ_RUN_TO_AREA: { CollectParameters(&m_nIp, 5); @@ -5045,6 +5070,7 @@ int8 CRunningScript::ProcessCommands500To599(int32 command) pPed->SetObjective(OBJECTIVE_RUN_TO_AREA, pos, radius); return 0; } + */ case COMMAND_SET_CHAR_OBJ_RUN_TO_COORD: { CollectParameters(&m_nIp, 3); @@ -5058,6 +5084,7 @@ int8 CRunningScript::ProcessCommands500To599(int32 command) pPed->SetObjective(OBJECTIVE_RUN_TO_AREA, pos); return 0; } + /* case COMMAND_IS_PLAYER_TOUCHING_OBJECT_ON_FOOT: { CollectParameters(&m_nIp, 2); @@ -5086,6 +5113,7 @@ int8 CRunningScript::ProcessCommands500To599(int32 command) UpdateCompareFlag(isTouching); return 0; } + */ case COMMAND_LOAD_SPECIAL_CHARACTER: { CollectParameters(&m_nIp, 1); @@ -5103,6 +5131,7 @@ int8 CRunningScript::ProcessCommands500To599(int32 command) UpdateCompareFlag(CStreaming::HasSpecialCharLoaded(ScriptParams[0] - 1)); return 0; } + /* case COMMAND_FLASH_CAR: { CollectParameters(&m_nIp, 2); @@ -5127,10 +5156,12 @@ int8 CRunningScript::ProcessCommands500To599(int32 command) pObject->bHasBlip = (ScriptParams[1] != 0); return 0; } + */ case COMMAND_IS_PLAYER_IN_REMOTE_MODE: CollectParameters(&m_nIp, 1); UpdateCompareFlag(CWorld::Players[ScriptParams[0]].IsPlayerInRemoteMode()); return 0; + /* case COMMAND_ARM_CAR_WITH_BOMB: { CollectParameters(&m_nIp, 2); @@ -5141,6 +5172,7 @@ int8 CRunningScript::ProcessCommands500To599(int32 command) ((CAutomobile*)pVehicle)->m_pBombRigger = FindPlayerPed(); return 0; } + */ case COMMAND_SET_CHAR_PERSONALITY: { CollectParameters(&m_nIp, 2); @@ -5161,6 +5193,7 @@ int8 CRunningScript::ProcessCommands500To599(int32 command) pPed->m_animGroup = (AssocGroupId)ScriptParams[1]; return 0; } + /* case COMMAND_SET_ANIM_GROUP_FOR_PLAYER: { CollectParameters(&m_nIp, 2); @@ -5169,6 +5202,7 @@ int8 CRunningScript::ProcessCommands500To599(int32 command) pPed->m_animGroup = (AssocGroupId)ScriptParams[1]; return 0; } + */ case COMMAND_REQUEST_MODEL: { CollectParameters(&m_nIp, 1); @@ -5203,6 +5237,7 @@ int8 CRunningScript::ProcessCommands500To599(int32 command) StoreParameters(&m_nIp, 1); return 0; } + /* case COMMAND_SET_REPEATED_PHONE_MESSAGE: { CollectParameters(&m_nIp, 1); @@ -5223,6 +5258,7 @@ int8 CRunningScript::ProcessCommands500To599(int32 command) UpdateCompareFlag(gPhoneInfo.HasMessageBeenDisplayed(ScriptParams[0])); return 0; } + */ case COMMAND_TURN_PHONE_OFF: { CollectParameters(&m_nIp, 1); @@ -5236,7 +5272,7 @@ int8 CRunningScript::ProcessCommands500To599(int32 command) if (pos.z <= MAP_Z_LOW_LIMIT) pos.z = CWorld::FindGroundZForCoord(pos.x, pos.y); CCoronas::RegisterCorona((uintptr)this + m_nIp, ScriptParams[6], ScriptParams[7], ScriptParams[8], - 255, pos, *(float*)&ScriptParams[3], 150.0f, ScriptParams[4], ScriptParams[5], 1, 0, 0, 0.0f); + 255, pos, *(float*)&ScriptParams[3], 150.0f, ScriptParams[4], ScriptParams[5], 1, 0, 0, 0.0f); // TODO(MIAMI): more params return 0; } case COMMAND_DRAW_LIGHT: @@ -5248,18 +5284,15 @@ int8 CRunningScript::ProcessCommands500To599(int32 command) ScriptParams[3] / 255.0f, ScriptParams[4] / 255.0f, ScriptParams[5] / 255.0f, 0, true); return 0; } - case COMMAND_STORE_WEATHER: - CWeather::StoreWeatherState(); - return 0; - case COMMAND_RESTORE_WEATHER: - CWeather::RestoreWeatherState(); - return 0; + //case COMMAND_STORE_WEATHER: + //case COMMAND_RESTORE_WEATHER: case COMMAND_STORE_CLOCK: CClock::StoreClock(); return 0; case COMMAND_RESTORE_CLOCK: CClock::RestoreClock(); return 0; + /* case COMMAND_RESTART_CRITICAL_MISSION: { CollectParameters(&m_nIp, 4); @@ -5272,6 +5305,7 @@ int8 CRunningScript::ProcessCommands500To599(int32 command) CWorld::Players[CWorld::PlayerInFocus].PlayerFailedCriticalMission(); return 0; } + */ case COMMAND_IS_PLAYER_PLAYING: { CollectParameters(&m_nIp, 1); @@ -5380,6 +5414,7 @@ int8 CRunningScript::ProcessCommands600To699(int32 command) ((CAutomobile*)pVehicle)->bFixedColour = (ScriptParams[1] == 0); return 0; } + /* case COMMAND_IS_TAXI: { CollectParameters(&m_nIp, 1); @@ -5388,6 +5423,7 @@ int8 CRunningScript::ProcessCommands600To699(int32 command) UpdateCompareFlag(pVehicle->IsTaxi()); return 0; } + */ case COMMAND_UNLOAD_SPECIAL_CHARACTER: CollectParameters(&m_nIp, 1); CStreaming::SetMissionDoesntRequireSpecialChar(ScriptParams[0] - 1); @@ -5400,6 +5436,7 @@ int8 CRunningScript::ProcessCommands600To699(int32 command) ScriptParams[0] = CDarkel::QueryModelsKilledByPlayer(ScriptParams[0]); StoreParameters(&m_nIp, 1); return 0; + /* case COMMAND_ACTIVATE_GARAGE: CollectParameters(&m_nIp, 1); CGarages::ActivateGarage(ScriptParams[0]); @@ -5415,6 +5452,7 @@ int8 CRunningScript::ProcessCommands600To699(int32 command) } return 0; } + */ case COMMAND_CREATE_OBJECT_NO_OFFSET: { CollectParameters(&m_nIp, 4); @@ -5428,6 +5466,9 @@ int8 CRunningScript::ProcessCommands600To699(int32 command) pObj->SetOrientation(0.0f, 0.0f, 0.0f); pObj->GetMatrix().UpdateRW(); pObj->UpdateRwFrame(); + CBaseModelInfo* pModelInfo = CModelInfo::GetModelInfo(mi); + if (pModelInfo->IsBuilding() && ((CSimpleModelInfo*)pModelInfo)->m_isBigBuilding) + pObj->SetupBigBuilding(); CTheScripts::ClearSpaceForMissionEntity(pos, pObj); CWorld::Add(pObj); ScriptParams[0] = CPools::GetObjectPool()->GetIndex(pObj); @@ -5436,6 +5477,7 @@ int8 CRunningScript::ProcessCommands600To699(int32 command) CTheScripts::MissionCleanup.AddEntityToList(ScriptParams[0], CLEANUP_OBJECT); return 0; } + /* case COMMAND_IS_BOAT: { CollectParameters(&m_nIp, 1); @@ -5470,6 +5512,7 @@ int8 CRunningScript::ProcessCommands600To699(int32 command) pPed->SetObjective(OBJECTIVE_GOTO_AREA_ANY_MEANS, pos, radius); return 0; } + */ //case COMMAND_SET_COLL_OBJ_GOTO_AREA_ANY_MEANS: case COMMAND_IS_PLAYER_STOPPED: { @@ -5477,7 +5520,9 @@ int8 CRunningScript::ProcessCommands600To699(int32 command) CPlayerInfo* pPlayer = &CWorld::Players[ScriptParams[0]]; UpdateCompareFlag(CTheScripts::IsPlayerStopped(pPlayer)); return 0; + } + /* case COMMAND_IS_CHAR_STOPPED: { CollectParameters(&m_nIp, 1); @@ -5500,6 +5545,7 @@ int8 CRunningScript::ProcessCommands600To699(int32 command) CParticleObject::AddObject(ScriptParams[0], pos, ScriptParams[4] != 0); return 0; } + */ case COMMAND_SWITCH_WIDESCREEN: CollectParameters(&m_nIp, 1); if (ScriptParams[0] != 0) @@ -5507,6 +5553,7 @@ int8 CRunningScript::ProcessCommands600To699(int32 command) else TheCamera.SetWideScreenOff(); return 0; + /* case COMMAND_ADD_SPRITE_BLIP_FOR_CAR: { CollectParameters(&m_nIp, 2); @@ -5543,6 +5590,7 @@ int8 CRunningScript::ProcessCommands600To699(int32 command) StoreParameters(&m_nIp, 1); return 0; } + */ case COMMAND_ADD_SPRITE_BLIP_FOR_CONTACT_POINT: { CollectParameters(&m_nIp, 4); @@ -5623,6 +5671,7 @@ int8 CRunningScript::ProcessCommands600To699(int32 command) case COMMAND_IS_PLAYER_STOPPED_IN_ANGLED_AREA_IN_CAR_3D: PlayerInAngledAreaCheckCommand(command, &m_nIp); return 0; + /* case COMMAND_DEACTIVATE_GARAGE: CollectParameters(&m_nIp, 1); CGarages::DeActivateGarage(ScriptParams[0]); @@ -5636,6 +5685,7 @@ int8 CRunningScript::ProcessCommands600To699(int32 command) CollectParameters(&m_nIp, 2); UpdateCompareFlag(CGarages::HasThisCarBeenCollected(ScriptParams[0], ScriptParams[1] - 1)); return 0; + */ default: assert(0); } @@ -5645,6 +5695,7 @@ int8 CRunningScript::ProcessCommands600To699(int32 command) int8 CRunningScript::ProcessCommands700To799(int32 command) { switch (command){ + /* case COMMAND_SET_SWAT_REQUIRED: CollectParameters(&m_nIp, 1); FindPlayerPed()->m_pWanted->m_bSwatRequired = (ScriptParams[0] != 0); @@ -5657,6 +5708,7 @@ int8 CRunningScript::ProcessCommands700To799(int32 command) CollectParameters(&m_nIp, 1); FindPlayerPed()->m_pWanted->m_bArmyRequired = (ScriptParams[0] != 0); return 0; + */ case COMMAND_IS_CAR_IN_WATER: { CollectParameters(&m_nIp, 1); @@ -5701,10 +5753,11 @@ int8 CRunningScript::ProcessCommands700To799(int32 command) pVehicle->AutoPilot.m_nCarMission = MISSION_GOTOCOORDS_ACCURATE; pVehicle->SetStatus(STATUS_PHYSICS); pVehicle->bEngineOn = true; - pVehicle->AutoPilot.m_nCruiseSpeed = Max(6, pVehicle->AutoPilot.m_nCruiseSpeed); + pVehicle->AutoPilot.m_nCruiseSpeed = Max(1, pVehicle->AutoPilot.m_nCruiseSpeed); pVehicle->AutoPilot.m_nAntiReverseTimer = CTimer::GetTimeInMilliseconds(); return 0; } + /* case COMMAND_START_PACMAN_RACE: CollectParameters(&m_nIp, 1); CPacManPickups::StartPacManRace(ScriptParams[0]); @@ -5735,6 +5788,7 @@ int8 CRunningScript::ProcessCommands700To799(int32 command) case COMMAND_CLEAR_NUMBER_OF_POWER_PILLS_CARRIED: CPacManPickups::ResetPowerPillsCarriedByPlayer(); return 0; + */ case COMMAND_IS_CAR_ON_SCREEN: { CollectParameters(&m_nIp, 1); @@ -5759,6 +5813,7 @@ int8 CRunningScript::ProcessCommands700To799(int32 command) UpdateCompareFlag(TheCamera.IsSphereVisible(pObject->GetBoundCentre(), pObject->GetBoundRadius())); return 0; } + /* case COMMAND_GOSUB_FILE: { CollectParameters(&m_nIp, 2); @@ -5768,6 +5823,7 @@ int8 CRunningScript::ProcessCommands700To799(int32 command) // ScriptParams[1] == filename return 0; } + */ case COMMAND_GET_GROUND_Z_FOR_3D_COORD: { CollectParameters(&m_nIp, 3); @@ -5795,6 +5851,7 @@ int8 CRunningScript::ProcessCommands700To799(int32 command) CollectParameters(&m_nIp, 1); gFireManager.RemoveScriptFire(ScriptParams[0]); return 0; + /* case COMMAND_SET_COMEDY_CONTROLS: { CollectParameters(&m_nIp, 2); @@ -5803,6 +5860,7 @@ int8 CRunningScript::ProcessCommands700To799(int32 command) pVehicle->bComedyControls = (ScriptParams[1] != 0); return 0; } + */ case COMMAND_BOAT_GOTO_COORDS: { CollectParameters(&m_nIp, 4); @@ -5816,7 +5874,7 @@ int8 CRunningScript::ProcessCommands700To799(int32 command) pBoat->AutoPilot.m_nCarMission = MISSION_GOTOCOORDS_ASTHECROWSWIMS; pBoat->AutoPilot.m_vecDestinationCoors = pos; pBoat->SetStatus(STATUS_PHYSICS); - pBoat->AutoPilot.m_nCruiseSpeed = Max(6, pBoat->AutoPilot.m_nCruiseSpeed); + pBoat->AutoPilot.m_nCruiseSpeed = Max(1, pBoat->AutoPilot.m_nCruiseSpeed); pBoat->AutoPilot.m_nAntiReverseTimer = CTimer::GetTimeInMilliseconds(); return 0; } @@ -5872,7 +5930,7 @@ int8 CRunningScript::ProcessCommands700To799(int32 command) CollectParameters(&m_nIp, 2); CPed* pPed = CWorld::Players[ScriptParams[0]].m_pPed; assert(pPed); - UpdateCompareFlag(ScriptParams[1] == pPed->m_weapons[pPed->m_currentWeapon].m_eWeaponType); + UpdateCompareFlag(ScriptParams[1] == pPed->GetWeapon()->m_eWeaponType); return 0; } case COMMAND_IS_CURRENT_CHAR_WEAPON: @@ -5880,9 +5938,10 @@ int8 CRunningScript::ProcessCommands700To799(int32 command) CollectParameters(&m_nIp, 2); CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]); assert(pPed); - UpdateCompareFlag(ScriptParams[1] == pPed->m_weapons[pPed->m_currentWeapon].m_eWeaponType); + UpdateCompareFlag(ScriptParams[1] == pPed->GetWeapon()->m_eWeaponType); return 0; } + /* case COMMAND_CLEAR_NUMBER_OF_POWER_PILLS_EATEN: CPacManPickups::ResetPowerPillsEatenInRace(); return 0; @@ -5895,6 +5954,7 @@ int8 CRunningScript::ProcessCommands700To799(int32 command) CPacManPickups::GenerateOnePMPickUp(pos); return 0; } + */ case COMMAND_SET_BOAT_CRUISE_SPEED: { CollectParameters(&m_nIp, 2); @@ -5905,6 +5965,7 @@ int8 CRunningScript::ProcessCommands700To799(int32 command) pBoat->AutoPilot.m_nCruiseSpeed = *(float*)&ScriptParams[1]; return 0; } + /* case COMMAND_GET_RANDOM_CHAR_IN_AREA: { CollectParameters(&m_nIp, 4); @@ -5953,6 +6014,7 @@ int8 CRunningScript::ProcessCommands700To799(int32 command) StoreParameters(&m_nIp, 1); return 0; } + */ case COMMAND_GET_RANDOM_CHAR_IN_ZONE: { char zone[KEY_LENGTH_IN_SCRIPT]; @@ -5961,6 +6023,7 @@ int8 CRunningScript::ProcessCommands700To799(int32 command) if (nZone != -1) m_nIp += KEY_LENGTH_IN_SCRIPT; CZone* pZone = CTheZones::GetNavigationZone(nZone); + CollectParameters(&m_nIp, 3); int ped_handle = -1; CVector pos = FindPlayerCoors(); int i = CPools::GetPedPool()->GetSize(); @@ -5978,9 +6041,9 @@ int8 CRunningScript::ProcessCommands700To799(int32 command) continue; if (pPed->bFadeOut) continue; -// if (pPed->GetModelIndex() == MI_SCUM_WOM || pPed->GetModelIndex() == MI_SCUM_MAN) -// continue; - if (!ThisIsAValidRandomPed(pPed->m_nPedType)) + if (pPed->m_nWaitState != WAITSTATE_FALSE) + continue; + if (!ThisIsAValidRandomPed(pPed->m_nPedType, ScriptParams[0], ScriptParams[1], ScriptParams[2])) continue; if (pPed->bIsLeader || pPed->m_leader) continue; @@ -5990,6 +6053,10 @@ int8 CRunningScript::ProcessCommands700To799(int32 command) continue; if (pos.z + PED_FIND_Z_OFFSET < pPed->GetPosition().z) continue; + bool found; + CWorld::FindRoofZFor3DCoord(pos.x, pos.y, pos.z, &found); + if (found) + continue; ped_handle = CPools::GetPedPool()->GetIndex(pPed); CTheScripts::LastRandomPedId = ped_handle; pPed->CharCreatedBy = MISSION_CHAR; @@ -6110,6 +6177,7 @@ int8 CRunningScript::ProcessCommands700To799(int32 command) CollectParameters(&m_nIp, 1); CWorld::Players[CWorld::PlayerInFocus].m_nTotalPackages = ScriptParams[0]; return 0; + /* case COMMAND_IS_PROJECTILE_IN_AREA: { CollectParameters(&m_nIp, 6); @@ -6180,6 +6248,7 @@ int8 CRunningScript::ProcessCommands700To799(int32 command) CPickups::GenerateNewOne(pos, MI_NAUTICALMINE, PICKUP_MINE_INACTIVE, 0); return 0; } + */ case COMMAND_IS_CHAR_MODEL: { CollectParameters(&m_nIp, 2); @@ -6199,16 +6268,8 @@ int8 CRunningScript::ProcessCommands700To799(int32 command) m_nIp += KEY_LENGTH_IN_SCRIPT; return 0; } - case COMMAND_CREATE_CUTSCENE_HEAD: - { - assert(0); - return 0; - } - case COMMAND_SET_CUTSCENE_HEAD_ANIM: - { - assert(0); - return 0; - } + //case COMMAND_CREATE_CUTSCENE_HEAD: + //case COMMAND_SET_CUTSCENE_HEAD_ANIM: case COMMAND_SIN: CollectParameters(&m_nIp, 1); *(float*)&ScriptParams[0] = Sin(DEGTORAD(*(float*)&ScriptParams[0])); @@ -6241,6 +6302,7 @@ int8 CRunningScript::ProcessCommands700To799(int32 command) CollectParameters(&m_nIp, 2); CGarages::ChangeGarageType(ScriptParams[0], (eGarageType)ScriptParams[1], 0); return 0; + /* case COMMAND_ACTIVATE_CRUSHER_CRANE: { CollectParameters(&m_nIp, 10); @@ -6258,7 +6320,7 @@ int8 CRunningScript::ProcessCommands700To799(int32 command) } CCranes::ActivateCrane(infX, supX, infY, supY, *(float*)&ScriptParams[6], *(float*)&ScriptParams[7], *(float*)&ScriptParams[8], - DEGTORAD(*(float*)&ScriptParams[8]), true, false, + DEGTORAD(*(float*)&ScriptParams[9]), true, false, *(float*)&ScriptParams[0], *(float*)&ScriptParams[1]); return 0; } @@ -6269,6 +6331,7 @@ int8 CRunningScript::ProcessCommands700To799(int32 command) CMessages::AddMessageWithNumber(text, ScriptParams[2], ScriptParams[3], ScriptParams[0], ScriptParams[1], -1, -1, -1, -1); return 0; } + */ case COMMAND_PRINT_WITH_2_NUMBERS_NOW: { wchar* text = CTheScripts::GetTextByKeyFromScript(&m_nIp); @@ -6276,6 +6339,7 @@ int8 CRunningScript::ProcessCommands700To799(int32 command) CMessages::AddMessageJumpQWithNumber(text, ScriptParams[2], ScriptParams[3], ScriptParams[0], ScriptParams[1], -1, -1, -1, -1); return 0; } + /* case COMMAND_PRINT_WITH_2_NUMBERS_SOON: { wchar* text = CTheScripts::GetTextByKeyFromScript(&m_nIp); @@ -6283,6 +6347,7 @@ int8 CRunningScript::ProcessCommands700To799(int32 command) CMessages::AddMessageSoonWithNumber(text, ScriptParams[2], ScriptParams[3], ScriptParams[0], ScriptParams[1], -1, -1, -1, -1); return 0; } + */ case COMMAND_PRINT_WITH_3_NUMBERS: { wchar* text = CTheScripts::GetTextByKeyFromScript(&m_nIp); @@ -6290,6 +6355,7 @@ int8 CRunningScript::ProcessCommands700To799(int32 command) CMessages::AddMessageWithNumber(text, ScriptParams[3], ScriptParams[4], ScriptParams[0], ScriptParams[1], ScriptParams[2], -1, -1, -1); return 0; } + /* case COMMAND_PRINT_WITH_3_NUMBERS_NOW: { wchar* text = CTheScripts::GetTextByKeyFromScript(&m_nIp); @@ -6304,6 +6370,7 @@ int8 CRunningScript::ProcessCommands700To799(int32 command) CMessages::AddMessageSoonWithNumber(text, ScriptParams[3], ScriptParams[4], ScriptParams[0], ScriptParams[1], ScriptParams[2], -1, -1, -1); return 0; } + */ case COMMAND_PRINT_WITH_4_NUMBERS: { wchar* text = CTheScripts::GetTextByKeyFromScript(&m_nIp); @@ -6311,6 +6378,7 @@ int8 CRunningScript::ProcessCommands700To799(int32 command) CMessages::AddMessageWithNumber(text, ScriptParams[4], ScriptParams[5], ScriptParams[0], ScriptParams[1], ScriptParams[2], ScriptParams[3], -1, -1); return 0; } + /* case COMMAND_PRINT_WITH_4_NUMBERS_NOW: { wchar* text = CTheScripts::GetTextByKeyFromScript(&m_nIp); @@ -6346,6 +6414,7 @@ int8 CRunningScript::ProcessCommands700To799(int32 command) CMessages::AddMessageSoonWithNumber(text, ScriptParams[5], ScriptParams[6], ScriptParams[0], ScriptParams[1], ScriptParams[2], ScriptParams[3], ScriptParams[4], -1); return 0; } + */ case COMMAND_PRINT_WITH_6_NUMBERS: { wchar* text = CTheScripts::GetTextByKeyFromScript(&m_nIp); @@ -6353,6 +6422,7 @@ int8 CRunningScript::ProcessCommands700To799(int32 command) CMessages::AddMessageWithNumber(text, ScriptParams[6], ScriptParams[7], ScriptParams[0], ScriptParams[1], ScriptParams[2], ScriptParams[3], ScriptParams[4], ScriptParams[5]); return 0; } + /* case COMMAND_PRINT_WITH_6_NUMBERS_NOW: { wchar* text = CTheScripts::GetTextByKeyFromScript(&m_nIp); @@ -6378,6 +6448,7 @@ int8 CRunningScript::ProcessCommands700To799(int32 command) pPed->SetFormation((eFormation)ScriptParams[2]); return 0; } + */ case COMMAND_PLAYER_MADE_PROGRESS: CollectParameters(&m_nIp, 1); CStats::ProgressMade += ScriptParams[0]; @@ -6385,6 +6456,8 @@ int8 CRunningScript::ProcessCommands700To799(int32 command) case COMMAND_SET_PROGRESS_TOTAL: CollectParameters(&m_nIp, 1); CStats::TotalProgressInGame = ScriptParams[0]; + if (CGame::germanGame) + CStats::TotalProgressInGame -= 2; return 0; case COMMAND_REGISTER_JUMP_DISTANCE: CollectParameters(&m_nIp, 1); @@ -6431,6 +6504,8 @@ int8 CRunningScript::ProcessCommands700To799(int32 command) strncpy(CStats::LastMissionPassedName, name, KEY_LENGTH_IN_SCRIPT); ++CStats::MissionsPassed; CStats::CheckPointReachedSuccessfully(); + CTheScripts::LastMissionPassedTime = CTimer::GetTimeInMilliseconds(); + //CGameLogic::RemoveShortCutDropOffPointForMission() // TODO(MIAMI) return 0; } case COMMAND_SET_CHAR_RUNNING: @@ -6444,6 +6519,7 @@ int8 CRunningScript::ProcessCommands700To799(int32 command) case COMMAND_REMOVE_ALL_SCRIPT_FIRES: gFireManager.RemoveAllScriptFires(); return 0; + /* case COMMAND_IS_FIRST_CAR_COLOUR: { CollectParameters(&m_nIp, 2); @@ -6460,22 +6536,37 @@ int8 CRunningScript::ProcessCommands700To799(int32 command) UpdateCompareFlag(pVehicle->m_currentColour2 == ScriptParams[1]); return 0; } + */ case COMMAND_HAS_CHAR_BEEN_DAMAGED_BY_WEAPON: { CollectParameters(&m_nIp, 2); CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]); + bool result = false; if (!pPed) printf("HAS_CHAR_BEEN_DAMAGED_BY_WEAPON - Character doesn't exist\n"); - UpdateCompareFlag(pPed && pPed->m_lastWepDam == ScriptParams[1]); + else { + if (ScriptParams[1] == WEAPONTYPE_ANYMELEE || ScriptParams[1] == WEAPONTYPE_ANYWEAPON) + result = CheckDamagedWeaponType(pPed->m_lastWepDam, ScriptParams[1]); + else + result = ScriptParams[1] == pPed->m_lastWepDam; + } + UpdateCompareFlag(result); return 0; } case COMMAND_HAS_CAR_BEEN_DAMAGED_BY_WEAPON: { CollectParameters(&m_nIp, 2); CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]); + bool result = false; if (!pVehicle) printf("HAS_CAR_BEEN_DAMAGED_BY_WEAPON - Vehicle doesn't exist\n"); - UpdateCompareFlag(pVehicle && pVehicle->m_nLastWeaponDamage == ScriptParams[1]); + else { + if (ScriptParams[1] == WEAPONTYPE_ANYMELEE || ScriptParams[1] == WEAPONTYPE_ANYWEAPON) + result = CheckDamagedWeaponType(pVehicle->m_nLastWeaponDamage, ScriptParams[1]); + else + result = ScriptParams[1] == pVehicle->m_nLastWeaponDamage; + } + UpdateCompareFlag(result); return 0; } case COMMAND_IS_CHAR_IN_CHARS_GROUP: @@ -6512,17 +6603,7 @@ int8 CRunningScript::ProcessCommands800To899(int32 command) CollectParameters(&m_nIp, 1); CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]); assert(pPed); - if (pPed->m_nPedState == PED_DRIVING) { - pPed->SetDead(); - if (!pPed->IsPlayer()) - pPed->FlagToDestroyWhenNextProcessed(); - } - else if (CGame::nastyGame && pPed->IsPedInControl()) { - pPed->ApplyHeadShot(WEAPONTYPE_SNIPERRIFLE, pPed->GetNodePosition(PED_HEAD), true); - } - else { - pPed->SetDie(ANIM_KO_SHOT_FRONT1, 4.0f, 0.0f); - } + pPed->InflictDamage(nil, WEAPONTYPE_SNIPERRIFLE, 1000.0f, PEDPIECE_HEAD, 0); return 0; } case COMMAND_EXPLODE_PLAYER_HEAD: @@ -6530,12 +6611,7 @@ int8 CRunningScript::ProcessCommands800To899(int32 command) CollectParameters(&m_nIp, 1); CPed* pPed = CWorld::Players[ScriptParams[0]].m_pPed; assert(pPed); - if (CGame::nastyGame) { - pPed->ApplyHeadShot(WEAPONTYPE_SNIPERRIFLE, pPed->GetNodePosition(PED_HEAD), true); - } - else { - pPed->SetDie(ANIM_KO_SHOT_FRONT1, 4.0f, 0.0f); - } + pPed->InflictDamage(nil, WEAPONTYPE_SNIPERRIFLE, 1000.0f, PEDPIECE_HEAD, 0); return 0; } case COMMAND_ANCHOR_BOAT: @@ -6591,6 +6667,10 @@ int8 CRunningScript::ProcessCommands800To899(int32 command) CVehicle* pVehicle = CPools::GetVehiclePool()->GetSlot(i); if (!pVehicle) continue; + if (pVehicle->GetVehicleAppearance() != VEHICLE_APPEARANCE_CAR && pVehicle->GetVehicleAppearance() != VEHICLE_APPEARANCE_BIKE) + continue; + if (!pVehicle->bUsesCollision) + continue; if (ScriptParams[4] != pVehicle->GetModelIndex() && ScriptParams[4] >= 0) continue; if (pVehicle->VehicleCreatedBy != RANDOM_VEHICLE) @@ -6608,11 +6688,11 @@ int8 CRunningScript::ProcessCommands800To899(int32 command) StoreParameters(&m_nIp, 1); return 0; } + /* case COMMAND_GET_RANDOM_CAR_OF_TYPE_IN_ZONE: { char zone[KEY_LENGTH_IN_SCRIPT]; CTheScripts::ReadTextLabelFromScript(&m_nIp, zone); -// TODO(MIAMI): just getting this to compile with new argument int zone_id = CTheZones::FindZoneByLabelAndReturnIndex(zone, ZONE_DEFAULT); if (zone_id != -1) m_nIp += KEY_LENGTH_IN_SCRIPT; @@ -6641,6 +6721,7 @@ int8 CRunningScript::ProcessCommands800To899(int32 command) StoreParameters(&m_nIp, 1); return 0; } + */ case COMMAND_HAS_RESPRAY_HAPPENED: { CollectParameters(&m_nIp, 1); @@ -6680,6 +6761,7 @@ int8 CRunningScript::ProcessCommands800To899(int32 command) CCarAI::TellCarToRamOtherCar(pVehicle, pTarget); return 0; } + /* case COMMAND_SET_CAR_BLOCK_CAR: { CollectParameters(&m_nIp, 2); @@ -6699,6 +6781,7 @@ int8 CRunningScript::ProcessCommands800To899(int32 command) pPed->SetObjective(OBJECTIVE_CATCH_TRAIN); return 0; } + */ //case COMMAND_SET_COLL_OBJ_CATCH_TRAIN: case COMMAND_SET_PLAYER_NEVER_GETS_TIRED: { @@ -6722,6 +6805,7 @@ int8 CRunningScript::ProcessCommands800To899(int32 command) pPed->bPedIsBleeding = (ScriptParams[1] != 0); return 0; } + /* case COMMAND_SET_CAR_FUNNY_SUSPENSION: { CollectParameters(&m_nIp, 2); @@ -6740,6 +6824,7 @@ int8 CRunningScript::ProcessCommands800To899(int32 command) pCar->bBigWheels = (ScriptParams[1] != 0); return 0; } + */ case COMMAND_SET_FREE_RESPRAYS: CollectParameters(&m_nIp, 1); CGarages::SetFreeResprays(ScriptParams[0] != 0); @@ -6760,6 +6845,7 @@ int8 CRunningScript::ProcessCommands800To899(int32 command) pPed->bIsVisible = (ScriptParams[1] != 0); return 0; } + /* case COMMAND_SET_CAR_VISIBLE: { CollectParameters(&m_nIp, 2); @@ -6768,6 +6854,7 @@ int8 CRunningScript::ProcessCommands800To899(int32 command) pVehicle->bIsVisible = (ScriptParams[1] != 0); return 0; } + */ case COMMAND_IS_AREA_OCCUPIED: { CollectParameters(&m_nIp, 11); @@ -6795,6 +6882,7 @@ int8 CRunningScript::ProcessCommands800To899(int32 command) UpdateCompareFlag(total > 0); return 0; } + /* case COMMAND_START_DRUG_RUN: CPlane::CreateIncomingCesna(); return 0; @@ -6808,6 +6896,7 @@ int8 CRunningScript::ProcessCommands800To899(int32 command) CollectParameters(&m_nIp, 1); gFireManager.ExtinguishPoint(CWorld::Players[ScriptParams[0]].GetPos(), 3.0f); return 0; + */ case COMMAND_DISPLAY_TEXT: { CollectParameters(&m_nIp, 2); @@ -6854,18 +6943,21 @@ int8 CRunningScript::ProcessCommands800To899(int32 command) CTheScripts::IntroTextLines[CTheScripts::NumberOfIntroTextLinesThisFrame].m_fWrapX = *(float*)&ScriptParams[0]; return 0; } + /* case COMMAND_SET_TEXT_CENTRE_SIZE: { CollectParameters(&m_nIp, 1); CTheScripts::IntroTextLines[CTheScripts::NumberOfIntroTextLinesThisFrame].m_fCenterSize = *(float*)&ScriptParams[0]; return 0; } + */ case COMMAND_SET_TEXT_BACKGROUND: { CollectParameters(&m_nIp, 1); CTheScripts::IntroTextLines[CTheScripts::NumberOfIntroTextLinesThisFrame].m_bBackground = (ScriptParams[0] != 0); return 0; } + /* case COMMAND_SET_TEXT_BACKGROUND_COLOUR: { CollectParameters(&m_nIp, 4); @@ -6879,12 +6971,14 @@ int8 CRunningScript::ProcessCommands800To899(int32 command) CTheScripts::IntroTextLines[CTheScripts::NumberOfIntroTextLinesThisFrame].m_bBackgroundOnly = (ScriptParams[0] != 0); return 0; } + */ case COMMAND_SET_TEXT_PROPORTIONAL: { CollectParameters(&m_nIp, 1); CTheScripts::IntroTextLines[CTheScripts::NumberOfIntroTextLinesThisFrame].m_bTextProportional = (ScriptParams[0] != 0); return 0; } + /* case COMMAND_SET_TEXT_FONT: { CollectParameters(&m_nIp, 1); @@ -6902,6 +6996,7 @@ int8 CRunningScript::ProcessCommands800To899(int32 command) case COMMAND_SUBURBAN_PASSED: CStats::SuburbanPassed = true; return 0; + */ case COMMAND_ROTATE_OBJECT: { CollectParameters(&m_nIp, 4); @@ -6910,7 +7005,11 @@ int8 CRunningScript::ProcessCommands800To899(int32 command) float heading = LimitAngleOnCircle( RADTODEG(Atan2(-pObject->GetForward().x, pObject->GetForward().y))); float headingTarget = *(float*)&ScriptParams[1]; +#ifdef FIX_BUGS + float rotateBy = *(float*)&ScriptParams[2] * CTimer::GetTimeStepFix(); +#else float rotateBy = *(float*)&ScriptParams[2]; +#endif if (headingTarget == heading) { // using direct comparasion here is fine UpdateCompareFlag(true); return 0; @@ -6959,7 +7058,11 @@ int8 CRunningScript::ProcessCommands800To899(int32 command) assert(pObject); CVector pos = pObject->GetPosition(); CVector posTarget = *(CVector*)&ScriptParams[1]; +#ifdef FIX_BUGS + CVector slideBy = *(CVector*)&ScriptParams[4] * CTimer::GetTimeStepFix(); +#else CVector slideBy = *(CVector*)&ScriptParams[4]; +#endif if (posTarget == pos) { // using direct comparasion here is fine UpdateCompareFlag(true); return 0; @@ -7011,28 +7114,16 @@ int8 CRunningScript::ProcessCommands800To899(int32 command) CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]); if (pPed && pPed->CharCreatedBy == MISSION_CHAR){ CWorld::RemoveReferencesToDeletedObject(pPed); - if (pPed->bInVehicle){ - if (pPed->m_pMyVehicle){ - if (pPed == pPed->m_pMyVehicle->pDriver){ - pPed->m_pMyVehicle->RemoveDriver(); - pPed->m_pMyVehicle->SetStatus(STATUS_ABANDONED); - if (pPed->m_pMyVehicle->m_nDoorLock == CARLOCK_LOCKED_INITIALLY) - pPed->m_pMyVehicle->m_nDoorLock = CARLOCK_UNLOCKED; - if (pPed->m_nPedType == PEDTYPE_COP && pPed->m_pMyVehicle->IsLawEnforcementVehicle()) - pPed->m_pMyVehicle->ChangeLawEnforcerState(0); - }else{ - pPed->m_pMyVehicle->RemovePassenger(pPed); - } - } - delete pPed; - --CPopulation::ms_nTotalMissionPeds; - }else{ + if (pPed->bInVehicle && pPed->m_pMyVehicle) + CTheScripts::RemoveThisPed(pPed); + else{ pPed->CharCreatedBy = RANDOM_CHAR; pPed->bRespondsToThreats = true; pPed->bScriptObjectiveCompleted = false; pPed->ClearLeader(); --CPopulation::ms_nTotalMissionPeds; pPed->bFadeOut = true; + CWorld::RemoveReferencesToDeletedObject(pPed); } } if (m_bIsMissionScript) @@ -7047,9 +7138,11 @@ int8 CRunningScript::ProcessCommands800To899(int32 command) pPed->bKindaStayInSamePlace = (ScriptParams[1] != 0); return 0; } + /* case COMMAND_IS_NASTY_GAME: UpdateCompareFlag(CGame::nastyGame); return 0; + */ case COMMAND_UNDRESS_CHAR: { CollectParameters(&m_nIp, 1); @@ -7079,6 +7172,7 @@ int8 CRunningScript::ProcessCommands800To899(int32 command) CWorld::Add(pPed); return 0; } + /* case COMMAND_START_CHASE_SCENE: CollectParameters(&m_nIp, 1); CTimer::Suspend(); @@ -7151,6 +7245,7 @@ int8 CRunningScript::ProcessCommands800To899(int32 command) StoreParameters(&m_nIp, 1); return 0; } + */ case COMMAND_PLACE_OBJECT_RELATIVE_TO_CAR: { CollectParameters(&m_nIp, 5); @@ -7177,7 +7272,7 @@ int8 CRunningScript::ProcessCommands800To899(int32 command) CollectParameters(&m_nIp, 2); CPlayerPed* pPlayerPed = CWorld::Players[ScriptParams[0]].m_pPed; assert(pPlayerPed); - pPlayerPed->m_fArmour = clamp(pPlayerPed->m_fArmour + ScriptParams[1], 0.0f, 100.0f); + pPlayerPed->m_fArmour = clamp(pPlayerPed->m_fArmour + ScriptParams[1], 0.0f, CWorld::Players[ScriptParams[0]].m_nMaxArmour); return 0; } case COMMAND_ADD_ARMOUR_TO_CHAR: @@ -7203,7 +7298,7 @@ int8 CRunningScript::ProcessCommands800To899(int32 command) case COMMAND_WARP_CHAR_FROM_CAR_TO_COORD: { CollectParameters(&m_nIp, 4); - CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]); + CPed *pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]); assert(pPed); CVector pos = *(CVector*)&ScriptParams[1]; if (pos.z <= MAP_Z_LOW_LIMIT) @@ -7216,26 +7311,48 @@ int8 CRunningScript::ProcessCommands800To899(int32 command) pPed->m_pMyVehicle->SetStatus(STATUS_ABANDONED); pPed->m_pMyVehicle->bEngineOn = false; pPed->m_pMyVehicle->AutoPilot.m_nCruiseSpeed = 0; + pPed->m_pMyVehicle->SetMoveSpeed(0.0f, 0.0f, -0.00001f); + pPed->m_pMyVehicle->SetTurnSpeed(0.0f, 0.0f, 0.0f); }else{ pPed->m_pMyVehicle->RemovePassenger(pPed); } - pPed->m_pMyVehicle->SetMoveSpeed(0.0f, 0.0f, -0.00001f); - pPed->m_pMyVehicle->SetTurnSpeed(0.0f, 0.0f, 0.0f); + if (pPed->m_vehEnterType) { + if (pPed->GetPedState() == PED_EXIT_CAR || pPed->GetPedState() == PED_DRAG_FROM_CAR) { + uint8 flags = 0; + if (pPed->m_pMyVehicle->IsBike()) { + //TODO(MIAMI) + } + else { + switch (pPed->m_vehEnterType) { + case CAR_DOOR_LF: + flags = pPed->m_pMyVehicle->m_nNumMaxPassengers != 0 ? CAR_DOOR_FLAG_LF : CAR_DOOR_FLAG_LF | CAR_DOOR_FLAG_LR; + case CAR_DOOR_LR: + flags = pPed->m_pMyVehicle->m_nNumMaxPassengers != 0 ? CAR_DOOR_FLAG_RF : CAR_DOOR_FLAG_LF | CAR_DOOR_FLAG_LR; + case CAR_DOOR_RF: + flags = CAR_DOOR_FLAG_RF; + case CAR_DOOR_RR: + flags = CAR_DOOR_FLAG_RR; + } + } + pPed->m_pMyVehicle->m_nGettingOutFlags &= ~flags; + pPed->m_pMyVehicle->ProcessOpenDoor(pPed->m_vehEnterType, NUM_STD_ANIMS, 0.0f); + } + } } + pPed->RemoveInCarAnims(); pPed->bInVehicle = false; pPed->m_pMyVehicle = nil; pPed->SetPedState(PED_IDLE); pPed->m_nLastPedState = PED_NONE; pPed->bUsesCollision = true; pPed->SetMoveSpeed(0.0f, 0.0f, 0.0f); - pPed->AddWeaponModel(CWeaponInfo::GetWeaponInfo(pPed->m_weapons[pPed->m_currentWeapon].m_eWeaponType)->m_nModelId); - pPed->RemoveInCarAnims(); + pPed->ReplaceWeaponWhenExitingVehicle(); if (pPed->m_pVehicleAnim) pPed->m_pVehicleAnim->blendDelta = -1000.0f; pPed->m_pVehicleAnim = nil; pPed->RestartNonPartialAnims(); pPed->SetMoveState(PEDMOVE_NONE); - CAnimManager::BlendAnimation(pPed->GetClump(), pPed->m_animGroup, ANIM_IDLE_STANCE, 100.0f); + CAnimManager::BlendAnimation(pPed->GetClump(), pPed->m_animGroup, ANIM_IDLE_STANCE, 1000.0f); pos.z += pPed->GetDistanceFromCentreOfMassToBaseOfModel(); pPed->Teleport(pos); CTheScripts::ClearSpaceForMissionEntity(pos, pPed); @@ -7271,6 +7388,7 @@ int8 CRunningScript::ProcessCommands800To899(int32 command) } return 0; } + /* case COMMAND_HAS_CHAR_SPOTTED_CHAR: { CollectParameters(&m_nIp, 2); @@ -7281,6 +7399,7 @@ int8 CRunningScript::ProcessCommands800To899(int32 command) UpdateCompareFlag(pPed->OurPedCanSeeThisOne(pTarget)); return 0; } + */ case COMMAND_SET_CHAR_OBJ_HAIL_TAXI: { CollectParameters(&m_nIp, 1); @@ -7298,6 +7417,7 @@ int8 CRunningScript::ProcessCommands800To899(int32 command) UpdateCompareFlag(pObject->bRenderDamaged || !pObject->bIsVisible); return 0; } + /* case COMMAND_START_KILL_FRENZY_HEADSHOT: { wchar* text = CTheScripts::GetTextByKeyFromScript(&m_nIp); @@ -7328,6 +7448,7 @@ int8 CRunningScript::ProcessCommands800To899(int32 command) *(float*)&ScriptParams[0], *(float*)&ScriptParams[1]); return 0; } + */ case COMMAND_WARP_PLAYER_INTO_CAR: { CollectParameters(&m_nIp, 2); @@ -7359,6 +7480,7 @@ int8 CRunningScript::ProcessCommands800To899(int32 command) CMessages::AddBigMessageWithNumber(text, ScriptParams[2], ScriptParams[3] - 1, ScriptParams[0], ScriptParams[1], -1, -1, -1, -1); return 0; } + /* case COMMAND_PRINT_WITH_3_NUMBERS_BIG: { wchar* text = CTheScripts::GetTextByKeyFromScript(&m_nIp); @@ -7387,6 +7509,7 @@ int8 CRunningScript::ProcessCommands800To899(int32 command) CMessages::AddBigMessageWithNumber(text, ScriptParams[6], ScriptParams[7] - 1, ScriptParams[0], ScriptParams[1], ScriptParams[2], ScriptParams[3], ScriptParams[4], ScriptParams[5]); return 0; } + */ case COMMAND_SET_CHAR_WAIT_STATE: { CollectParameters(&m_nIp, 3); @@ -7398,6 +7521,7 @@ int8 CRunningScript::ProcessCommands800To899(int32 command) case COMMAND_SET_CAMERA_BEHIND_PLAYER: TheCamera.SetCameraDirectlyBehindForFollowPed_CamOnAString(); return 0; + /* case COMMAND_SET_MOTION_BLUR: CollectParameters(&m_nIp, 1); TheCamera.SetMotionBlur(0, 0, 0, 0, ScriptParams[0]); @@ -7410,6 +7534,7 @@ int8 CRunningScript::ProcessCommands800To899(int32 command) CMessages::AddMessageWithString(text, ScriptParams[0], ScriptParams[1], string); return 0; } + */ case COMMAND_CREATE_RANDOM_CHAR: { CollectParameters(&m_nIp, 3); @@ -7432,6 +7557,7 @@ int8 CRunningScript::ProcessCommands800To899(int32 command) ped->CharCreatedBy = MISSION_CHAR; ped->bRespondsToThreats = false; ped->bAllowMedicsToReviveMe = false; + ped->bIsPlayerFriend = false; CVector pos = *(CVector*)&ScriptParams[0]; if (pos.z <= MAP_Z_LOW_LIMIT) pos.z = CWorld::FindGroundZForCoord(pos.x, pos.y); @@ -7459,6 +7585,7 @@ int8 CRunningScript::ProcessCommands800To899(int32 command) pPed->SetObjective(OBJECTIVE_STEAL_ANY_CAR); return 0; } + /* case COMMAND_SET_2_REPEATED_PHONE_MESSAGES: { CollectParameters(&m_nIp, 1); @@ -7513,6 +7640,7 @@ int8 CRunningScript::ProcessCommands800To899(int32 command) gPhoneInfo.SetPhoneMessage_JustOnce(ScriptParams[0], text1, text2, text3, text4, nil, nil); return 0; } + */ case COMMAND_IS_SNIPER_BULLET_IN_AREA: { CollectParameters(&m_nIp, 6); @@ -7537,9 +7665,11 @@ int8 CRunningScript::ProcessCommands800To899(int32 command) UpdateCompareFlag(CBulletInfo::TestForSniperBullet(infX, supX, infY, supY, infZ, supZ)); return 0; } + /* case COMMAND_GIVE_PLAYER_DETONATOR: CGarages::GivePlayerDetonator(); return 0; + */ //case COMMAND_SET_COLL_OBJ_STEAL_ANY_CAR: case COMMAND_SET_OBJECT_VELOCITY: { @@ -7589,6 +7719,7 @@ int8 CRunningScript::ProcessCommands900To999(int32 command) return 0; } //case COMMAND_PRINT_STRING_IN_STRING_SOON: + /* case COMMAND_SET_5_REPEATED_PHONE_MESSAGES: { CollectParameters(&m_nIp, 1); @@ -7635,6 +7766,7 @@ int8 CRunningScript::ProcessCommands900To999(int32 command) gPhoneInfo.SetPhoneMessage_JustOnce(ScriptParams[0], text1, text2, text3, text4, text5, text6); return 0; } + */ case COMMAND_IS_POINT_OBSCURED_BY_A_MISSION_ENTITY: { CollectParameters(&m_nIp, 6); @@ -7665,16 +7797,24 @@ int8 CRunningScript::ProcessCommands900To999(int32 command) return 0; } case COMMAND_LOAD_ALL_MODELS_NOW: +#ifdef FIX_BUGS + CTimer::Suspend(); +#else CTimer::Stop(); +#endif CStreaming::LoadAllRequestedModels(false); +#ifdef FIX_BUGS + CTimer::Resume(); +#else CTimer::Update(); +#endif return 0; case COMMAND_ADD_TO_OBJECT_VELOCITY: { CollectParameters(&m_nIp, 4); CObject* pObject = CPools::GetObjectPool()->GetAt(ScriptParams[0]); assert(pObject); - pObject->SetMoveSpeed(pObject->GetMoveSpeed() + 0.02f * *(CVector*)&ScriptParams[1]); + pObject->SetMoveSpeed(pObject->GetMoveSpeed() + *(CVector*)&ScriptParams[1] / METERS_PER_SECOND_TO_GAME_SPEED); return 0; } case COMMAND_DRAW_SPRITE: @@ -7728,9 +7868,7 @@ int8 CRunningScript::ProcessCommands900To999(int32 command) } case COMMAND_REMOVE_TEXTURE_DICTIONARY: { - for (int i = 0; i < ARRAY_SIZE(CTheScripts::ScriptSprites); i++) - CTheScripts::ScriptSprites[i].Delete(); - CTxdStore::RemoveTxd(CTxdStore::FindTxdSlot("script")); + CTheScripts::RemoveScriptTextureDictionary(); return 0; } case COMMAND_SET_OBJECT_DYNAMIC: @@ -7752,6 +7890,7 @@ int8 CRunningScript::ProcessCommands900To999(int32 command) } return 0; } + /* case COMMAND_SET_CHAR_ANIM_SPEED: { CollectParameters(&m_nIp, 2); @@ -7762,6 +7901,7 @@ int8 CRunningScript::ProcessCommands900To999(int32 command) pAssoc->speed = *(float*)&ScriptParams[1]; return 0; } + */ case COMMAND_PLAY_MISSION_PASSED_TUNE: { CollectParameters(&m_nIp, 1); @@ -7790,6 +7930,7 @@ int8 CRunningScript::ProcessCommands900To999(int32 command) pVehicle->m_bSirenOrAlarm = ScriptParams[1] != 0; return 0; } + /* case COMMAND_SWITCH_PED_ROADS_ON_ANGLED: { CollectParameters(&m_nIp, 7); @@ -7812,14 +7953,19 @@ int8 CRunningScript::ProcessCommands900To999(int32 command) ThePaths.SwitchRoadsInAngledArea(*(float*)&ScriptParams[0], *(float*)&ScriptParams[1], *(float*)&ScriptParams[2], *(float*)&ScriptParams[3], *(float*)&ScriptParams[4], *(float*)&ScriptParams[5], *(float*)&ScriptParams[6], 1, 0); return 0; + */ case COMMAND_SET_CAR_WATERTIGHT: { CollectParameters(&m_nIp, 2); CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]); assert(pVehicle); - assert(pVehicle->m_vehType == VEHICLE_TYPE_CAR); - CAutomobile* pCar = (CAutomobile*)pVehicle; - pCar->bWaterTight = ScriptParams[1] != 0; + if (pVehicle->IsBike()) { + //TODO(MIAMI) + } + else if (pVehicle->IsCar()) { + CAutomobile* pCar = (CAutomobile*)pVehicle; + pCar->bWaterTight = ScriptParams[1] != 0; + } return 0; } case COMMAND_ADD_MOVING_PARTICLE_EFFECT: @@ -7863,6 +8009,7 @@ int8 CRunningScript::ProcessCommands900To999(int32 command) pVehicle->SetHeading(heading); return 0; } + /* case COMMAND_IS_CRANE_LIFTING_CAR: { CollectParameters(&m_nIp, 3); @@ -7870,6 +8017,7 @@ int8 CRunningScript::ProcessCommands900To999(int32 command) UpdateCompareFlag(CCranes::IsThisCarPickedUp(*(float*)&ScriptParams[0], *(float*)&ScriptParams[1], pVehicle)); return 0; } + */ case COMMAND_DRAW_SPHERE: { CollectParameters(&m_nIp, 4); @@ -7906,6 +8054,7 @@ int8 CRunningScript::ProcessCommands900To999(int32 command) strncpy(m_abScriptName, str, KEY_LENGTH_IN_SCRIPT); return 0; } + /* case COMMAND_CHANGE_GARAGE_TYPE_WITH_CAR_MODEL: { CollectParameters(&m_nIp, 3); @@ -7916,6 +8065,7 @@ int8 CRunningScript::ProcessCommands900To999(int32 command) *(CVector*)&ScriptParams[0] = CPlane::FindDrugPlaneCoordinates(); StoreParameters(&m_nIp, 3); return 0; + */ case COMMAND_SAVE_INT_TO_DEBUG_FILE: // TODO: implement something here CollectParameters(&m_nIp, 1); @@ -7943,7 +8093,7 @@ int8 CRunningScript::ProcessCommands900To999(int32 command) return 0; case COMMAND_SWITCH_RUBBISH: CollectParameters(&m_nIp, 1); - CRubbish::SetVisibility(ScriptParams[0] != 0);; + CRubbish::SetVisibility(ScriptParams[0] != 0); return 0; case COMMAND_REMOVE_PARTICLE_EFFECTS_IN_AREA: { @@ -7982,6 +8132,7 @@ int8 CRunningScript::ProcessCommands900To999(int32 command) CollectParameters(&m_nIp, 1); UpdateCompareFlag(CGarages::IsGarageClosed(ScriptParams[0])); return 0; + /* case COMMAND_START_CATALINA_HELI: CHeli::StartCatalinaFlyBy(); return 0; @@ -7994,6 +8145,7 @@ int8 CRunningScript::ProcessCommands900To999(int32 command) case COMMAND_HAS_CATALINA_HELI_BEEN_SHOT_DOWN: UpdateCompareFlag(CHeli::HasCatalinaBeenShotDown()); return 0; + */ case COMMAND_SWAP_NEAREST_BUILDING_MODEL: { CollectParameters(&m_nIp, 6); @@ -8040,6 +8192,7 @@ int8 CRunningScript::ProcessCommands900To999(int32 command) pPed->ClearWeapons(); return 0; } + /* case COMMAND_GRAB_CATALINA_HELI: { CHeli* pHeli = CHeli::FindPointerToCatalinasHeli(); @@ -8047,6 +8200,7 @@ int8 CRunningScript::ProcessCommands900To999(int32 command) StoreParameters(&m_nIp, 1); return 0; } + */ case COMMAND_CLEAR_AREA_OF_CARS: { CollectParameters(&m_nIp, 6); @@ -8091,9 +8245,11 @@ int8 CRunningScript::ProcessCommands900To999(int32 command) CollectParameters(&m_nIp, 1); CTheScripts::RemoveScriptSphere(ScriptParams[0]); return 0; + /* case COMMAND_CATALINA_HELI_FLY_AWAY: CHeli::MakeCatalinaHeliFlyAway(); return 0; + */ case COMMAND_SET_EVERYONE_IGNORE_PLAYER: { CollectParameters(&m_nIp, 2); @@ -8128,18 +8284,21 @@ int8 CRunningScript::ProcessCommands900To999(int32 command) StoreParameters(&m_nIp, 1); return 0; } + /* case COMMAND_IS_PHONE_DISPLAYING_MESSAGE: CollectParameters(&m_nIp, 1); UpdateCompareFlag(gPhoneInfo.IsMessageBeingDisplayed(ScriptParams[0])); return 0; + */ case COMMAND_DISPLAY_ONSCREEN_TIMER_WITH_STRING: { assert(CTheScripts::ScriptSpace[m_nIp++] == ARGUMENT_GLOBALVAR); int16 var = CTheScripts::Read2BytesFromScript(&m_nIp); + CollectParameters(&m_nIp, 1); wchar* text = TheText.Get((char*)&CTheScripts::ScriptSpace[m_nIp]); // ??? strncpy(onscreen_str, (char*)&CTheScripts::ScriptSpace[m_nIp], KEY_LENGTH_IN_SCRIPT); m_nIp += KEY_LENGTH_IN_SCRIPT; - CUserDisplay::OnscnTimer.AddClock(var, onscreen_str); + CUserDisplay::OnscnTimer.AddClock(var, onscreen_str, ScriptParams[0] != 0); return 0; } case COMMAND_DISPLAY_ONSCREEN_COUNTER_WITH_STRING: @@ -8150,7 +8309,7 @@ int8 CRunningScript::ProcessCommands900To999(int32 command) wchar* text = TheText.Get((char*)&CTheScripts::ScriptSpace[m_nIp]); // ??? strncpy(onscreen_str, (char*)&CTheScripts::ScriptSpace[m_nIp], KEY_LENGTH_IN_SCRIPT); m_nIp += KEY_LENGTH_IN_SCRIPT; - CUserDisplay::OnscnTimer.AddCounter(var, ScriptParams[0], onscreen_str); + CUserDisplay::OnscnTimer.AddCounter(var, ScriptParams[0], onscreen_str, 0); return 0; } case COMMAND_CREATE_RANDOM_CAR_FOR_CAR_PARK: @@ -8175,15 +8334,17 @@ int8 CRunningScript::ProcessCommands900To999(int32 command) switch (model) { case MI_LANDSTAL: case MI_LINERUN: + case MI_RIO: case MI_FIRETRUCK: case MI_TRASH: case MI_STRETCH: + case MI_VOODOO: case MI_MULE: case MI_AMBULAN: case MI_FBICAR: case MI_MRWHOOP: case MI_BFINJECT: - // case MI_CORPSE: + case MI_HUNTER: case MI_POLICE: case MI_ENFORCER: case MI_SECURICA: @@ -8191,42 +8352,73 @@ int8 CRunningScript::ProcessCommands900To999(int32 command) case MI_BUS: case MI_RHINO: case MI_BARRACKS: - case MI_TRAIN: + case MI_CUBAN: case MI_CHOPPER: - case MI_DODO: + case MI_ANGEL: case MI_COACH: case MI_RCBANDIT: - // case MI_BELLYUP: - // case MI_MRWONGS: - // case MI_MAFIA: - case MI_VOODOO: - // case MI_YAKUZA: - // case MI_DIABLOS: - // case MI_COLUMB: - // case MI_HOODS: + case MI_ROMERO: + case MI_PACKER: + case MI_SENTXS: + case MI_SQUALO: + case MI_SEASPAR: + case MI_PIZZABOY: + case MI_GANGBUR: case MI_AIRTRAIN: case MI_DEADDODO: case MI_SPEEDER: case MI_REEFER: - // case MI_PANLANT: + case MI_TROPIC: case MI_FLATBED: case MI_YANKEE: - // case MI_ESCAPE: + case MI_CADDY: case MI_ZEBRA: case MI_TOPFUN: - // case MI_GHOST: + case MI_SKIMMER: case MI_RCBARON: case MI_RCRAIDER: + case MI_SPARROW: + case MI_PATRIOT: + case MI_LOVEFIST: + case MI_COASTG: + case MI_DINGHY: + case MI_HERMES: + case MI_SABRETUR: + case MI_PHEONIX: + case MI_WALTON: + case MI_COMET: + case MI_DELUXO: + case MI_BURRITO: + case MI_SPAND: + case MI_MARQUIS: + case MI_BAGGAGE: + case MI_KAUFMAN: + case MI_MAVERICK: + case MI_VCNMAV: + case MI_RANCHER: + case MI_FBIRANCH: + case MI_JETMAX: + case MI_HOTRING: + case MI_SANDKING: + case MI_BLISTAC: + case MI_POLMAV: + case MI_BOXVILLE: + case MI_BENSON: + case MI_MESA: + case MI_RCGOBLIN: + case MI_HOTRINA: + case MI_HOTRINB: + case MI_BLOODRA: + case MI_BLOODRB: + case MI_VICECHEE: model = -1; break; case MI_IDAHO: case MI_STINGER: case MI_PEREN: case MI_SENTINEL: - case MI_PATRIOT: case MI_MANANA: case MI_INFERNUS: - // case MI_BLISTA: case MI_PONY: case MI_CHEETAH: case MI_MOONBEAM: @@ -8238,9 +8430,17 @@ int8 CRunningScript::ProcessCommands900To999(int32 command) case MI_CABBIE: case MI_STALLION: case MI_RUMPO: -// case 151: -// case 152: -// case 153: + case MI_ADMIRAL: + case MI_PCJ600: + case MI_FAGGIO: + case MI_FREEWAY: + case MI_GLENDALE: + case MI_OCEANIC: + case MI_SANCHEZ: + case MI_SABRE: + case MI_REGINA: + case MI_VIRGO: + case MI_GREENWOO: break; default: printf("CREATE_RANDOM_CAR_FOR_CAR_PARK - Unknown car model %d\n", CStreaming::ms_vehiclesLoaded[index]); @@ -8256,15 +8456,15 @@ int8 CRunningScript::ProcessCommands900To999(int32 command) if (model == -1) return 0; CVehicle* car; - if (!CModelInfo::IsBikeModel(model)) - car = new CAutomobile(model, MISSION_VEHICLE); + //if (CModelInfo::IsBikeModel(model)) // TODO(MIAMI) + car = new CAutomobile(model, MISSION_VEHICLE); CVector pos = *(CVector*)&ScriptParams[0]; pos.z += car->GetDistanceFromCentreOfMassToBaseOfModel(); car->SetPosition(pos); car->SetHeading(DEGTORAD(*(float*)&ScriptParams[3])); CTheScripts::ClearSpaceForMissionEntity(pos, car); car->SetStatus(STATUS_ABANDONED); - car->bIsLocked = true; + car->bIsLocked = false; car->bIsCarParkVehicle = true; CCarCtrl::JoinCarWithRoadSystem(car); car->AutoPilot.m_nCarMission = MISSION_NONE; @@ -8277,10 +8477,12 @@ int8 CRunningScript::ProcessCommands900To999(int32 command) CWorld::Add(car); return 0; } + /* case COMMAND_IS_COLLISION_IN_MEMORY: CollectParameters(&m_nIp, 1); UpdateCompareFlag(CCollision::ms_collisionInMemory == ScriptParams[0]); return 0; + */ case COMMAND_SET_WANTED_MULTIPLIER: CollectParameters(&m_nIp, 1); FindPlayerPed()->m_pWanted->m_fCrimeSensitivity = *(float*)&ScriptParams[0]; @@ -8288,6 +8490,7 @@ int8 CRunningScript::ProcessCommands900To999(int32 command) case COMMAND_SET_CAMERA_IN_FRONT_OF_PLAYER: TheCamera.SetCameraDirectlyInFrontForFollowPed_CamOnAString(); return 0; + /* case COMMAND_IS_CAR_VISIBLY_DAMAGED: { CollectParameters(&m_nIp, 1); @@ -8296,6 +8499,7 @@ int8 CRunningScript::ProcessCommands900To999(int32 command) UpdateCompareFlag(pVehicle->bIsDamaged); return 0; } + */ case COMMAND_DOES_OBJECT_EXIST: CollectParameters(&m_nIp, 1); UpdateCompareFlag(CPools::GetObjectPool()->GetAt(ScriptParams[0])); @@ -8304,9 +8508,17 @@ int8 CRunningScript::ProcessCommands900To999(int32 command) { CollectParameters(&m_nIp, 3); CVector pos = *(CVector*)&ScriptParams[0]; +#ifdef FIX_BUGS + CTimer::Suspend(); +#else CTimer::Stop(); +#endif CStreaming::LoadScene(pos); +#ifdef FIX_BUGS + CTimer::Suspend(); +#else CTimer::Update(); +#endif return 0; } case COMMAND_ADD_STUCK_CAR_CHECK: @@ -8328,21 +8540,49 @@ int8 CRunningScript::ProcessCommands900To999(int32 command) UpdateCompareFlag(CTheScripts::StuckCars.HasCarBeenStuckForAWhile(ScriptParams[0])); return 0; case COMMAND_LOAD_MISSION_AUDIO: + { + CollectParameters(&m_nIp, 1); strncpy(str, (char*)&CTheScripts::ScriptSpace[m_nIp], KEY_LENGTH_IN_SCRIPT); for (int i = 0; i < KEY_LENGTH_IN_SCRIPT; i++) str[i] = tolower(str[i]); + static bool bShowed = false; m_nIp += KEY_LENGTH_IN_SCRIPT; - DMAudio.PreloadMissionAudio(str); + if (!bShowed) { + debug("LOAD_MISSION_AUDIO not implemented\n"); + bShowed = true; + } + //DMAudio.PreloadMissionAudio(str); return 0; + } case COMMAND_HAS_MISSION_AUDIO_LOADED: - UpdateCompareFlag(DMAudio.GetMissionAudioLoadingStatus() == 1); + { + CollectParameters(&m_nIp, 1); + static bool bShowed = false; + if (!bShowed) { + debug("HAS_MISSION_AUDIO_LOADED not implemented, default to TRUE\n"); + bShowed = true; + } + UpdateCompareFlag(true); + //UpdateCompareFlag(DMAudio.GetMissionAudioLoadingStatus() == 1); return 0; + } case COMMAND_PLAY_MISSION_AUDIO: - DMAudio.PlayLoadedMissionAudio(); + CollectParameters(&m_nIp, 1); + debug("PLAY_MISSION_AUDIO doesn't support parameter yet, skipping\n"); + //DMAudio.PlayLoadedMissionAudio(); return 0; case COMMAND_HAS_MISSION_AUDIO_FINISHED: - UpdateCompareFlag(DMAudio.IsMissionAudioSampleFinished()); + { + CollectParameters(&m_nIp, 1); + static bool bShowed = false; + if (!bShowed) { + debug("HAS_MISSION_AUDIO_FINISHED not implemented, default to TRUE\n"); + bShowed = true; + } + UpdateCompareFlag(true); + //UpdateCompareFlag(DMAudio.IsMissionAudioSampleFinished()); return 0; + } case COMMAND_GET_CLOSEST_CAR_NODE_WITH_HEADING: { CollectParameters(&m_nIp, 3); @@ -8350,6 +8590,7 @@ int8 CRunningScript::ProcessCommands900To999(int32 command) if (pos.z <= MAP_Z_LOW_LIMIT) pos.z = CWorld::FindGroundZForCoord(pos.x, pos.y); int node = ThePaths.FindNodeClosestToCoors(pos, 0, 999999.9f, true, true); + // TODO(MIAMI): replace GetPosition with FindNodeCoorsForScript *(CVector*)&ScriptParams[0] = ThePaths.m_pathNodes[node].GetPosition(); *(float*)&ScriptParams[3] = ThePaths.FindNodeOrientationForCarPlacement(node); StoreParameters(&m_nIp, 4); @@ -8375,21 +8616,32 @@ int8 CRunningScript::ProcessCommands900To999(int32 command) } case COMMAND_SET_MISSION_AUDIO_POSITION: { - CollectParameters(&m_nIp, 3); - CVector pos = *(CVector*)&ScriptParams[0]; - DMAudio.SetMissionAudioLocation(pos.x, pos.y, pos.z); + CollectParameters(&m_nIp, 4); + CVector pos = *(CVector*)&ScriptParams[1]; + static bool bShowed = false; + if (!bShowed) { + debug("SET_MISSION_AUDIO_POSITION not implemented\n"); + bShowed = true; + } + //DMAudio.SetMissionAudioLocation(pos.x, pos.y, pos.z); return 0; } case COMMAND_ACTIVATE_SAVE_MENU: - FrontEndMenuManager.m_bSaveMenuActive = true; + { + CStats::SafeHouseVisits++; + FrontEndMenuManager.m_bActivateSaveMenu = true; + FindPlayerPed()->SetMoveSpeed(0.0f, 0.0f, 0.0f); + FindPlayerPed()->SetTurnSpeed(0.0f, 0.0f, 0.0f); return 0; + } case COMMAND_HAS_SAVE_GAME_FINISHED: - UpdateCompareFlag(!FrontEndMenuManager.m_bMenuActive); + UpdateCompareFlag(!FrontEndMenuManager.m_bMenuActive && !FrontEndMenuManager.m_bActivateSaveMenu); return 0; case COMMAND_NO_SPECIAL_CAMERA_FOR_THIS_GARAGE: CollectParameters(&m_nIp, 1); CGarages::SetLeaveCameraForThisGarage(ScriptParams[0]); return 0; + /* case COMMAND_ADD_BLIP_FOR_PICKUP_OLD: { CollectParameters(&m_nIp, 3); @@ -8399,6 +8651,7 @@ int8 CRunningScript::ProcessCommands900To999(int32 command) StoreParameters(&m_nIp, 1); return 0; } + */ case COMMAND_ADD_BLIP_FOR_PICKUP: { CollectParameters(&m_nIp, 1); @@ -8410,6 +8663,7 @@ int8 CRunningScript::ProcessCommands900To999(int32 command) StoreParameters(&m_nIp, 1); return 0; } + /* case COMMAND_ADD_SPRITE_BLIP_FOR_PICKUP: { CollectParameters(&m_nIp, 2); @@ -8421,6 +8675,7 @@ int8 CRunningScript::ProcessCommands900To999(int32 command) StoreParameters(&m_nIp, 1); return 0; } + */ case COMMAND_SET_PED_DENSITY_MULTIPLIER: CollectParameters(&m_nIp, 1); CPopulation::PedDensityMultiplier = *(float*)&ScriptParams[0]; @@ -8429,10 +8684,12 @@ int8 CRunningScript::ProcessCommands900To999(int32 command) CollectParameters(&m_nIp, 1); CPopulation::m_AllRandomPedsThisType = ScriptParams[0]; return 0; + /* case COMMAND_SET_TEXT_DRAW_BEFORE_FADE: CollectParameters(&m_nIp, 1); CTheScripts::IntroTextLines[CTheScripts::NumberOfIntroTextLinesThisFrame].m_bTextBeforeFade = ScriptParams[0] != 0; return 0; + */ case COMMAND_GET_COLLECTABLE1S_COLLECTED: ScriptParams[0] = CWorld::Players[CWorld::PlayerInFocus].m_nCollectedPackages; StoreParameters(&m_nIp, 1); @@ -8459,8 +8716,8 @@ int8 CRunningScript::ProcessCommands900To999(int32 command) if (CCamera::m_bUseMouse3rdPerson && ( strncmp((char*)&CTheScripts::ScriptSpace[m_nIp], "HELP15", 7) == 0 || strncmp((char*)&CTheScripts::ScriptSpace[m_nIp], "GUN_2A", 7) == 0 || - strncmp((char*)&CTheScripts::ScriptSpace[m_nIp], "GUN_3A", 7) == 0 || - strncmp((char*)&CTheScripts::ScriptSpace[m_nIp], "GUN_4A", 7) == 0)) { + strncmp((char*)&CTheScripts::ScriptSpace[m_nIp], "GUN_2C", 7) == 0 || + strncmp((char*)&CTheScripts::ScriptSpace[m_nIp], "GUN_2D", 7) == 0)) { m_nIp += KEY_LENGTH_IN_SCRIPT; return 0; } @@ -8483,11 +8740,9 @@ int8 CRunningScript::ProcessCommands900To999(int32 command) int8 CRunningScript::ProcessCommands1000To1099(int32 command) { -#ifdef GTA_PS2 - char tmp[48]; -#endif switch (command) { //case COMMAND_FLASH_RADAR_BLIP: + /* case COMMAND_IS_CHAR_IN_CONTROL: { CollectParameters(&m_nIp, 1); @@ -8495,6 +8750,7 @@ int8 CRunningScript::ProcessCommands1000To1099(int32 command) UpdateCompareFlag(pPed->IsPedInControl()); return 0; } + */ case COMMAND_SET_GENERATE_CARS_AROUND_CAMERA: CollectParameters(&m_nIp, 1); CCarCtrl::bCarsGeneratedAroundCamera = (ScriptParams[0] != 0); @@ -8502,9 +8758,11 @@ int8 CRunningScript::ProcessCommands1000To1099(int32 command) case COMMAND_CLEAR_SMALL_PRINTS: CMessages::ClearSmallMessagesOnly(); return 0; + /* case COMMAND_HAS_MILITARY_CRANE_COLLECTED_ALL_CARS: UpdateCompareFlag(CCranes::HaveAllCarsBeenCollectedByMilitaryCrane()); return 0; + */ case COMMAND_SET_UPSIDEDOWN_CAR_NOT_DAMAGED: { CollectParameters(&m_nIp, 2); @@ -8570,6 +8828,7 @@ int8 CRunningScript::ProcessCommands1000To1099(int32 command) return 0; } //case COMMAND_MAKE_PLAYER_UNSAFE: + /* case COMMAND_LOAD_COLLISION: { CollectParameters(&m_nIp, 1); @@ -8584,9 +8843,10 @@ int8 CRunningScript::ProcessCommands1000To1099(int32 command) return 0; } case COMMAND_GET_BODY_CAST_HEALTH: - ScriptParams[0] = CObject::nBodyCastHealth; - StoreParameters(&m_nIp, 1); + // ScriptParams[0] = CObject::nBodyCastHealth; + // StoreParameters(&m_nIp, 1); return 0; + */ case COMMAND_SET_CHARS_CHATTING: { CollectParameters(&m_nIp, 3); @@ -8598,6 +8858,7 @@ int8 CRunningScript::ProcessCommands1000To1099(int32 command) return 0; } //case COMMAND_MAKE_PLAYER_SAFE: + /* case COMMAND_SET_CAR_STAYS_IN_CURRENT_LEVEL: { CollectParameters(&m_nIp, 2); @@ -8620,18 +8881,33 @@ int8 CRunningScript::ProcessCommands1000To1099(int32 command) pPed->m_nZoneLevel = LEVEL_NONE; return 0; } + */ case COMMAND_SET_DRUNK_INPUT_DELAY: - assert(0 && "SET_DRUNK_INPUT_DELAY not yet implemented"); + { + CollectParameters(&m_nIp, 2); + debug("SET_DRUNK_INPUT_DELAY not implemented\n"); return 0; + } case COMMAND_SET_CHAR_MONEY: - assert(0 && "SET_CHAR_MONEY not yet implemented"); - return 0; - case COMMAND_INCREASE_CHAR_MONEY: - assert(0 && "INCREASE_CHAR_MONEY not yet implemented"); + { + CollectParameters(&m_nIp, 2); + CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]); + assert(pPed); + pPed->m_nPedMoney = ScriptParams[1]; + pPed->bMoneyHasBeenGivenByScript = true; return 0; + } + //case COMMAND_INCREASE_CHAR_MONEY: case COMMAND_GET_OFFSET_FROM_OBJECT_IN_WORLD_COORDS: - assert(0 && "GET_OFFSET_FROM_OBJECT_IN_WORLD_COORDS not yet implemented"); + { + CollectParameters(&m_nIp, 4); + CObject* pObject = CPools::GetObjectPool()->GetAt(ScriptParams[0]); + assert(pObject); + CVector result = Multiply3x3(pObject->GetMatrix(), *(CVector*)&ScriptParams[1]) + pObject->GetPosition(); + *(CVector*)&ScriptParams[0] = result; + StoreParameters(&m_nIp, 3); return 0; + } case COMMAND_REGISTER_LIFE_SAVED: CStats::AnotherLifeSavedWithAmbulance(); return 0; @@ -8649,24 +8925,35 @@ int8 CRunningScript::ProcessCommands1000To1099(int32 command) CollectParameters(&m_nIp, 1); gPhoneInfo.m_aPhones[ScriptParams[0]].m_nState = PHONE_STATE_9; return 0; + /* case COMMAND_REGISTER_LONGEST_DODO_FLIGHT: CollectParameters(&m_nIp, 1); CStats::RegisterLongestFlightInDodo(ScriptParams[0]); return 0; + */ case COMMAND_GET_OFFSET_FROM_CAR_IN_WORLD_COORDS: - assert(0 && "GET_OFFSET_FROM_CAR_IN_WORLD_COORDS not yet implemented"); + { + CollectParameters(&m_nIp, 4); + CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]); + assert(pVehicle); + CVector result = Multiply3x3(pVehicle->GetMatrix(), *(CVector*)&ScriptParams[1]) + pVehicle->GetPosition(); + *(CVector*)&ScriptParams[0] = result; + StoreParameters(&m_nIp, 3); return 0; + } case COMMAND_SET_TOTAL_NUMBER_OF_KILL_FRENZIES: CollectParameters(&m_nIp, 1); CStats::SetTotalNumberKillFrenzies(ScriptParams[0]); return 0; case COMMAND_BLOW_UP_RC_BUGGY: - CWorld::Players[CWorld::PlayerInFocus].BlowUpRCBuggy(); + CWorld::Players[CWorld::PlayerInFocus].BlowUpRCBuggy(true); return 0; + /* case COMMAND_REMOVE_CAR_FROM_CHASE: CollectParameters(&m_nIp, 1); CRecordDataForChase::RemoveCarFromChase(ScriptParams[0]); return 0; + */ case COMMAND_IS_FRENCH_GAME: UpdateCompareFlag(CGame::frenchGame); return 0; @@ -8674,8 +8961,13 @@ int8 CRunningScript::ProcessCommands1000To1099(int32 command) UpdateCompareFlag(CGame::germanGame); return 0; case COMMAND_CLEAR_MISSION_AUDIO: - DMAudio.ClearMissionAudio(); + { + CollectParameters(&m_nIp, 1); + debug("CLEAR_MISSION_AUDIO not implemented\n"); + //DMAudio.ClearMissionAudio(); return 0; + } + /* case COMMAND_SET_FADE_IN_AFTER_NEXT_ARREST: CollectParameters(&m_nIp, 1); CRestart::bFadeInAfterNextArrest = !!ScriptParams[0]; @@ -8688,6 +8980,7 @@ int8 CRunningScript::ProcessCommands1000To1099(int32 command) CollectParameters(&m_nIp, 2); CGangs::SetGangPedModelOverride(ScriptParams[0], ScriptParams[1]); return 0; + */ case COMMAND_SET_CHAR_USE_PEDNODE_SEEK: { CollectParameters(&m_nIp, 2); @@ -8698,6 +8991,7 @@ int8 CRunningScript::ProcessCommands1000To1099(int32 command) pPed->bUsePedNodeSeek = !!ScriptParams[1]; return 0; } + /* case COMMAND_SWITCH_VEHICLE_WEAPONS: { CollectParameters(&m_nIp, 2); @@ -8710,10 +9004,12 @@ int8 CRunningScript::ProcessCommands1000To1099(int32 command) CollectParameters(&m_nIp, 2); CWorld::Players[ScriptParams[0]].m_bGetOutOfJailFree = !!ScriptParams[1]; return 0; + */ case COMMAND_SET_FREE_HEALTH_CARE: CollectParameters(&m_nIp, 2); CWorld::Players[ScriptParams[0]].m_bGetOutOfHospitalFree = !!ScriptParams[1]; return 0; + /* case COMMAND_IS_CAR_DOOR_CLOSED: { CollectParameters(&m_nIp, 2); @@ -8722,16 +9018,20 @@ int8 CRunningScript::ProcessCommands1000To1099(int32 command) UpdateCompareFlag(!pVehicle->IsDoorMissing((eDoors)ScriptParams[1]) && pVehicle->IsDoorClosed((eDoors)ScriptParams[1])); return 0; } + */ case COMMAND_LOAD_AND_LAUNCH_MISSION: return 0; case COMMAND_LOAD_AND_LAUNCH_MISSION_INTERNAL: { CollectParameters(&m_nIp, 1); + if (CTheScripts::NumberOfExclusiveMissionScripts > 0 && ScriptParams[0] <= UINT16_MAX - 2) + return 0; CTimer::Suspend(); int offset = CTheScripts::MultiScriptArray[ScriptParams[0]]; #ifdef USE_DEBUG_SCRIPT_LOADER CFileMgr::ChangeDir("\\data\\"); int handle = CFileMgr::OpenFile(scriptfile, "rb"); + CFileMgr::ChangeDir("\\"); #else CFileMgr::ChangeDir("\\"); int handle = CFileMgr::OpenFile("data\\main.scm", "rb"); @@ -8743,6 +9043,8 @@ int8 CRunningScript::ProcessCommands1000To1099(int32 command) CTimer::Resume(); pMissionScript->m_bIsMissionScript = true; pMissionScript->m_bMissionFlag = true; + CTheScripts::bAlreadyRunningAMissionScript = true; + //CGameLogic::ClearShortcut(); // TODO(MIAMI) return 0; } case COMMAND_SET_OBJECT_DRAW_LAST: @@ -8758,14 +9060,15 @@ int8 CRunningScript::ProcessCommands1000To1099(int32 command) CollectParameters(&m_nIp, 2); CPlayerPed* pPed = CWorld::Players[ScriptParams[0]].m_pPed; assert(pPed); - CWeapon* pWeaponSlot = &pPed->m_weapons[ScriptParams[1]]; - if (pWeaponSlot->m_eWeaponType == (eWeaponType)ScriptParams[1]) - ScriptParams[0] = pWeaponSlot->m_nAmmoTotal; - else - ScriptParams[0] = 0; + ScriptParams[0] = 0; + for (int i = 0; i < TOTAL_WEAPON_SLOTS; i++) { + if (pPed->GetWeapon(i).m_eWeaponType == (eWeaponType)ScriptParams[1]) + ScriptParams[0] = pPed->GetWeapon(i).m_nAmmoTotal; + } StoreParameters(&m_nIp, 1); return 0; } + /* case COMMAND_GET_AMMO_IN_CHAR_WEAPON: { CollectParameters(&m_nIp, 2); @@ -8810,6 +9113,7 @@ int8 CRunningScript::ProcessCommands1000To1099(int32 command) } return 0; } + */ case COMMAND_SET_NEAR_CLIP: CollectParameters(&m_nIp, 1); TheCamera.SetNearClipScript(*(float*)&ScriptParams[0]); @@ -8818,6 +9122,7 @@ int8 CRunningScript::ProcessCommands1000To1099(int32 command) CollectParameters(&m_nIp, 2); DMAudio.SetRadioChannel(ScriptParams[0], ScriptParams[1]); return 0; + /* case COMMAND_OVERRIDE_HOSPITAL_LEVEL: CollectParameters(&m_nIp, 1); CRestart::OverrideHospitalLevel = ScriptParams[0]; @@ -8838,6 +9143,7 @@ int8 CRunningScript::ProcessCommands1000To1099(int32 command) UpdateCompareFlag(CGarages::IsThisCarWithinGarageArea(ScriptParams[0], pVehicle)); return 0; } + */ case COMMAND_SET_CAR_TRACTION: { CollectParameters(&m_nIp, 2); @@ -8847,9 +9153,8 @@ int8 CRunningScript::ProcessCommands1000To1099(int32 command) if (pVehicle->m_vehType == VEHICLE_TYPE_CAR) ((CAutomobile*)pVehicle)->m_fTraction = fTraction; else - // this is certainly not a boat, trane, heli or plane field + // TODO(MIAMI) //((CBike*)pVehicle)->m_fTraction = fTraction; - *(float*)(((char*)pVehicle) + 1088) = fTraction; return 0; } case COMMAND_ARE_MEASUREMENTS_IN_METRES: @@ -8868,6 +9173,7 @@ int8 CRunningScript::ProcessCommands1000To1099(int32 command) StoreParameters(&m_nIp, 1); return 0; } + /* case COMMAND_MARK_ROADS_BETWEEN_LEVELS: { CollectParameters(&m_nIp, 6); @@ -8916,6 +9222,7 @@ int8 CRunningScript::ProcessCommands1000To1099(int32 command) ThePaths.PedMarkRoadsBetweenLevelsInArea(infX, supX, infY, supY, infZ, supZ); return 0; } + */ case COMMAND_SET_CAR_AVOID_LEVEL_TRANSITIONS: { CollectParameters(&m_nIp, 2); @@ -8924,6 +9231,7 @@ int8 CRunningScript::ProcessCommands1000To1099(int32 command) pVehicle->AutoPilot.m_bStayInCurrentLevel = !!ScriptParams[1]; return 0; } + /* case COMMAND_SET_CHAR_AVOID_LEVEL_TRANSITIONS: { CollectParameters(&m_nIp, 2); @@ -8936,6 +9244,7 @@ int8 CRunningScript::ProcessCommands1000To1099(int32 command) CollectParameters(&m_nIp, 2); UpdateCompareFlag(CPedType::IsThreat(ScriptParams[0], ScriptParams[1])); return 0; + */ case COMMAND_CLEAR_AREA_OF_CHARS: { CollectParameters(&m_nIp, 6); @@ -8962,7 +9271,7 @@ int8 CRunningScript::ProcessCommands1000To1099(int32 command) } case COMMAND_SET_TOTAL_NUMBER_OF_MISSIONS: CollectParameters(&m_nIp, 1); - CStats::SetTotalNumberMissions(ScriptParams[0]); + CStats::SetTotalNumberMissions(CGame::germanGame ? ScriptParams[0] - 2 : ScriptParams[0]); return 0; case COMMAND_CONVERT_METRES_TO_FEET_INT: CollectParameters(&m_nIp, 1); @@ -8978,7 +9287,15 @@ int8 CRunningScript::ProcessCommands1000To1099(int32 command) CStats::RegisterHighestScore(ScriptParams[0], ScriptParams[1]); return 0; //case COMMAND_WARP_CHAR_INTO_CAR_AS_PASSENGER: - //case COMMAND_IS_CAR_PASSENGER_SEAT_FREE: + case COMMAND_IS_CAR_PASSENGER_SEAT_FREE: + { + CollectParameters(&m_nIp, 2); + CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]); + assert(pVehicle); + UpdateCompareFlag(ScriptParams[1] < pVehicle->m_nNumMaxPassengers && pVehicle->pPassengers[ScriptParams[1]] == nil); + return 0; + } + /* case COMMAND_GET_CHAR_IN_CAR_PASSENGER_SEAT: { CollectParameters(&m_nIp, 2); @@ -8990,6 +9307,7 @@ int8 CRunningScript::ProcessCommands1000To1099(int32 command) StoreParameters(&m_nIp, 1); return 0; } + */ case COMMAND_SET_CHAR_IS_CHRIS_CRIMINAL: { CollectParameters(&m_nIp, 2); @@ -9012,6 +9330,7 @@ int8 CRunningScript::ProcessCommands1000To1099(int32 command) CParticle::AddParticle((tParticleType)ScriptParams[0], *(CVector*)&ScriptParams[1], *(CVector*)&ScriptParams[4], nil, *(float*)&ScriptParams[7], 0, 0, 0, 0); return 0; + /* case COMMAND_SET_CHAR_IGNORE_LEVEL_TRANSITIONS: { CollectParameters(&m_nIp, 2); @@ -9044,10 +9363,12 @@ int8 CRunningScript::ProcessCommands1000To1099(int32 command) CSpecialParticleStuff::UpdateBoatFoamAnimation(&pObject->GetMatrix()); return 0; } + */ case COMMAND_SET_MUSIC_DOES_FADE: CollectParameters(&m_nIp, 1); TheCamera.m_bIgnoreFadingStuffForMusic = (ScriptParams[0] == 0); return 0; + /* case COMMAND_SET_INTRO_IS_PLAYING: CollectParameters(&m_nIp, 1); if (ScriptParams[0]) { @@ -9062,6 +9383,7 @@ int8 CRunningScript::ProcessCommands1000To1099(int32 command) CStreaming::LoadAllRequestedModels(false); } return 0; + */ case COMMAND_SET_PLAYER_HOOKER: { CollectParameters(&m_nIp, 2); @@ -9074,6 +9396,7 @@ int8 CRunningScript::ProcessCommands1000To1099(int32 command) CPed* pHooker = CPools::GetPedPool()->GetAt(ScriptParams[1]); assert(pHooker); pPlayerInfo->m_pHooker = (CCivilianPed*)pHooker; + pPlayerInfo->m_nSexFrequency = 1000; pPlayerInfo->m_nNextSexFrequencyUpdateTime = CTimer::GetTimeInMilliseconds() + 1000; pPlayerInfo->m_nNextSexMoneyUpdateTime = CTimer::GetTimeInMilliseconds() + 3000; } @@ -9101,8 +9424,7 @@ int8 CRunningScript::ProcessCommands1000To1099(int32 command) CPlayerPed* pPed = CWorld::Players[ScriptParams[0]].m_pPed; assert(pPed); CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[1]); - assert(pVehicle); - UpdateCompareFlag(pPed->GetPedState() == PED_DRIVING && pPed->m_pMyVehicle == pVehicle); + UpdateCompareFlag(pPed->GetPedState() == PED_DRIVING && pPed->m_objective != OBJECTIVE_LEAVE_VEHICLE && pPed->m_pMyVehicle == pVehicle); return 0; } case COMMAND_IS_PLAYER_SITTING_IN_ANY_CAR: @@ -9110,15 +9432,17 @@ int8 CRunningScript::ProcessCommands1000To1099(int32 command) CollectParameters(&m_nIp, 1); CPlayerPed* pPed = CWorld::Players[ScriptParams[0]].m_pPed; assert(pPed); - UpdateCompareFlag(pPed->GetPedState() == PED_DRIVING); + UpdateCompareFlag(pPed->GetPedState() == PED_DRIVING && pPed->m_objective != OBJECTIVE_LEAVE_VEHICLE); return 0; } + /* case COMMAND_SET_SCRIPT_FIRE_AUDIO: CollectParameters(&m_nIp, 2); gFireManager.SetScriptFireAudio(ScriptParams[0], !!ScriptParams[1]); return 0; + */ case COMMAND_ARE_ANY_CAR_CHEATS_ACTIVATED: - UpdateCompareFlag(CVehicle::bAllDodosCheat || CVehicle::bCheat3); + UpdateCompareFlag(CVehicle::bAllDodosCheat || CVehicle::bCheat3); // TODO(MIAMI): more cheats! return 0; case COMMAND_SET_CHAR_SUFFERS_CRITICAL_HITS: { @@ -9128,6 +9452,7 @@ int8 CRunningScript::ProcessCommands1000To1099(int32 command) pPed->bNoCriticalHits = (ScriptParams[0] == 0); return 0; } + /* case COMMAND_IS_PLAYER_LIFTING_A_PHONE: { CollectParameters(&m_nIp, 1); @@ -9136,6 +9461,7 @@ int8 CRunningScript::ProcessCommands1000To1099(int32 command) UpdateCompareFlag(pPed->GetPedState() == PED_MAKE_CALL); return 0; } + */ case COMMAND_IS_CHAR_SITTING_IN_CAR: { CollectParameters(&m_nIp, 2); @@ -9143,7 +9469,7 @@ int8 CRunningScript::ProcessCommands1000To1099(int32 command) assert(pPed); CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[1]); assert(pVehicle); - UpdateCompareFlag(pPed->GetPedState() == PED_DRIVING && pPed->m_pMyVehicle == pVehicle); + UpdateCompareFlag(pPed->GetPedState() == PED_DRIVING && pPed->m_objective != OBJECTIVE_LEAVE_VEHICLE && pPed->m_pMyVehicle == pVehicle); return 0; } case COMMAND_IS_CHAR_SITTING_IN_ANY_CAR: @@ -9151,7 +9477,7 @@ int8 CRunningScript::ProcessCommands1000To1099(int32 command) CollectParameters(&m_nIp, 1); CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]); assert(pPed); - UpdateCompareFlag(pPed->GetPedState() == PED_DRIVING); + UpdateCompareFlag(pPed->GetPedState() == PED_DRIVING && pPed->m_objective != OBJECTIVE_LEAVE_VEHICLE); return 0; } case COMMAND_IS_PLAYER_ON_FOOT: @@ -9182,6 +9508,7 @@ int8 CRunningScript::ProcessCommands1100To1199(int32 command) { char tmp[48]; switch (command) { + /* case COMMAND_LOAD_COLLISION_WITH_SCREEN: CollectParameters(&m_nIp, 1); CTimer::Stop(); @@ -9202,6 +9529,7 @@ int8 CRunningScript::ProcessCommands1100To1199(int32 command) } CTimer::Update(); return 0; + */ case COMMAND_LOAD_SPLASH_SCREEN: CTheScripts::ReadTextLabelFromScript(&m_nIp, tmp); for (int i = 0; i < KEY_LENGTH_IN_SCRIPT; i++) @@ -9209,6 +9537,7 @@ int8 CRunningScript::ProcessCommands1100To1199(int32 command) m_nIp += 8; LoadSplash(tmp); return 0; + /* case COMMAND_SET_CAR_IGNORE_LEVEL_TRANSITIONS: { CollectParameters(&m_nIp, 2); @@ -9230,6 +9559,7 @@ int8 CRunningScript::ProcessCommands1100To1199(int32 command) pCar->bMoreResistantToDamage = ScriptParams[1]; return 0; } + */ case COMMAND_SET_JAMES_CAR_ON_PATH_TO_PLAYER: { CollectParameters(&m_nIp, 1); @@ -9244,9 +9574,11 @@ int8 CRunningScript::ProcessCommands1100To1199(int32 command) DMAudio.PreloadCutSceneMusic(STREAMED_SOUND_GAME_COMPLETED); printf("End preload end of game audio\n"); return 0; + /* case COMMAND_ENABLE_PLAYER_CONTROL_CAMERA: CPad::GetPad(0)->DisablePlayerControls &= PLAYERCONTROL_DISABLED_1; return 0; + */ case COMMAND_SET_OBJECT_ROTATION: { CollectParameters(&m_nIp, 4); @@ -9266,6 +9598,7 @@ int8 CRunningScript::ProcessCommands1100To1199(int32 command) *(CVector*)&ScriptParams[0] = TheCamera.Cams[2].Source; StoreParameters(&m_nIp, 3); return 0; + /* case COMMAND_GET_DEBUG_CAMERA_FRONT_VECTOR: *(CVector*)&ScriptParams[0] = TheCamera.Cams[2].Front; StoreParameters(&m_nIp, 3); @@ -9279,6 +9612,7 @@ int8 CRunningScript::ProcessCommands1100To1199(int32 command) UpdateCompareFlag(pTarget && pTarget->IsPed()); return 0; } + */ case COMMAND_IS_PLAYER_TARGETTING_CHAR: { CollectParameters(&m_nIp, 2); @@ -9287,9 +9621,38 @@ int8 CRunningScript::ProcessCommands1100To1199(int32 command) CPed* pTestedPed = CPools::GetPedPool()->GetAt(ScriptParams[1]); assert(pTestedPed); CEntity* pTarget = pPed->m_pPointGunAt; - UpdateCompareFlag(pTarget && pTarget->IsPed() && pTarget == pTestedPed); + bool bTargetting = pTarget && pTarget->IsPed() && pTarget == pTestedPed; + // PC shit + static int nCounter = 0; + nCounter = Max(0, nCounter - 1); + if (!pPed->GetWeapon()->IsTypeMelee() && !bTargetting) { + if ((pTestedPed->GetPosition() - TheCamera.GetPosition()).Magnitude() < 10.0f) { + CVector vTestedPos(pTestedPed->GetPosition().x, pTestedPed->GetPosition().y, pTestedPed->GetPosition().z + 0.4); + CVector vScreenPos; + float w, h; + if (CSprite::CalcScreenCoors(vTestedPos, vScreenPos, &w, &h, false)) { + CVector2D vCrosshairPosition(CCamera::m_f3rdPersonCHairMultX * RsGlobal.maximumWidth, CCamera::m_f3rdPersonCHairMultY * RsGlobal.maximumHeight); + float fScreenDistance = ((CVector2D)vScreenPos - vCrosshairPosition).Magnitude(); + if (SCREEN_STRETCH_X(0.45f) > fScreenDistance / w) { + CColPoint point; + CEntity* entity; + if (!CWorld::ProcessLineOfSight(TheCamera.GetPosition() + 2.0f * TheCamera.GetForward(), + vTestedPos, point, entity, true, true, true, true, true, false) || + entity == pTestedPed) { + nCounter += 2; + if (nCounter > 20) { + bTargetting = true; + nCounter = 20; + } + } + } + } + } + } + UpdateCompareFlag(bTargetting); return 0; } + /* case COMMAND_IS_PLAYER_TARGETTING_OBJECT: { CollectParameters(&m_nIp, 2); @@ -9301,6 +9664,7 @@ int8 CRunningScript::ProcessCommands1100To1199(int32 command) UpdateCompareFlag(pTarget && pTarget->IsObject() && pTarget == pTestedObject); return 0; } + */ case COMMAND_TERMINATE_ALL_SCRIPTS_WITH_THIS_NAME: { CTheScripts::ReadTextLabelFromScript(&m_nIp, tmp); @@ -9345,6 +9709,8 @@ int8 CRunningScript::ProcessCommands1100To1199(int32 command) return 0; case COMMAND_GET_CLOSEST_OBJECT_OF_TYPE: { + return 0; +/* CollectParameters(&m_nIp, 5); CVector pos = *(CVector*)&ScriptParams[0]; if (pos.z <= MAP_Z_LOW_LIMIT) @@ -9388,7 +9754,9 @@ int8 CRunningScript::ProcessCommands1100To1199(int32 command) } StoreParameters(&m_nIp, 1); return 0; +*/ } + /* case COMMAND_PLACE_OBJECT_RELATIVE_TO_OBJECT: { CollectParameters(&m_nIp, 5); @@ -9400,28 +9768,20 @@ int8 CRunningScript::ProcessCommands1100To1199(int32 command) CPhysical::PlacePhysicalRelativeToOtherPhysical(pTarget, pObject, offset); return 0; } + */ case COMMAND_SET_ALL_OCCUPANTS_OF_CAR_LEAVE_CAR: { CollectParameters(&m_nIp, 1); CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]); assert(pVehicle); - if (pVehicle->pDriver) { - pVehicle->pDriver->bScriptObjectiveCompleted = false; - pVehicle->pDriver->SetObjective(OBJECTIVE_LEAVE_VEHICLE, pVehicle); - } - for (int i = 0; i < ARRAY_SIZE(pVehicle->pPassengers); i++) - { - if (pVehicle->pPassengers[i]) { - pVehicle->pPassengers[i]->bScriptObjectiveCompleted = false; - pVehicle->pPassengers[i]->SetObjective(OBJECTIVE_LEAVE_VEHICLE, pVehicle); - } - } + CCarAI::TellOccupantsToLeaveCar(pVehicle); return 0; } case COMMAND_SET_INTERPOLATION_PARAMETERS: CollectParameters(&m_nIp, 2); - TheCamera.SetParametersForScriptInterpolation(*(float*)&ScriptParams[0], 50.0f - *(float*)&ScriptParams[0], ScriptParams[1]); + TheCamera.SetParametersForScriptInterpolation(*(float*)&ScriptParams[0], 100.0f - *(float*)&ScriptParams[0], ScriptParams[1]); return 0; + /* case COMMAND_GET_CLOSEST_CAR_NODE_WITH_HEADING_TOWARDS_POINT: { CollectParameters(&m_nIp, 5); @@ -9452,15 +9812,18 @@ int8 CRunningScript::ProcessCommands1100To1199(int32 command) StoreParameters(&m_nIp, 4); return 0; } + */ case COMMAND_GET_DEBUG_CAMERA_POINT_AT: *(CVector*)&ScriptParams[0] = TheCamera.Cams[2].Source + TheCamera.Cams[2].Front; StoreParameters(&m_nIp, 3); return 0; case COMMAND_ATTACH_CHAR_TO_CAR: - // empty implementation + // TODO(MIAMI) + assert(0); return 0; case COMMAND_DETACH_CHAR_FROM_CAR: - // empty implementation + // TODO(MIAMI) + assert(0); return 0; case COMMAND_SET_CAR_CHANGE_LANE: // for some reason changed in SA { @@ -9474,15 +9837,20 @@ int8 CRunningScript::ProcessCommands1100To1199(int32 command) { CollectParameters(&m_nIp, 1); CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]); - assert(pPed); - pPed->m_lastWepDam = -1; + if (pPed) + pPed->m_lastWepDam = -1; + else + debug("CLEAR_CHAR_LAST_WEAPON_DAMAGE - Character doesn't exist\n"); return 0; } case COMMAND_CLEAR_CAR_LAST_WEAPON_DAMAGE: { CollectParameters(&m_nIp, 1); CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]); - pVehicle->m_nLastWeaponDamage = -1; + if (pVehicle) + pVehicle->m_nLastWeaponDamage = -1; + else + debug("CLEAR_CAR_LAST_WEAPON_DAMAGE - Vehicle doesn't exist\n"); return 0; } case COMMAND_GET_RANDOM_COP_IN_AREA: @@ -9503,9 +9871,11 @@ int8 CRunningScript::ProcessCommands1100To1199(int32 command) continue; if (pPed->m_nPedType != PEDTYPE_COP) continue; + if (!ThisIsAValidRandomCop(pPed->GetModelIndex(), ScriptParams[4], ScriptParams[5], ScriptParams[6], ScriptParams[7], ScriptParams[8])) + continue; if (pPed->CharCreatedBy != RANDOM_CHAR) continue; - if (!pPed->IsPedInControl() && pPed->GetPedState() != PED_DRIVING) + if (!pPed->IsPedInControl() && pPed->GetPedState() != PED_DRIVING /* && pPed->GetPedState() != PED_ONROPE */) // TODO(MIAMI)! continue; if (pPed->bRemoveFromWorld) continue; @@ -9515,9 +9885,9 @@ int8 CRunningScript::ProcessCommands1100To1199(int32 command) continue; if (!pPed->IsWithinArea(x1, y1, x2, y2)) continue; - if (pos.z - PED_FIND_Z_OFFSET > pPed->GetPosition().z) + if (pos.z - COP_PED_FIND_Z_OFFSET > pPed->GetPosition().z) continue; - if (pos.z + PED_FIND_Z_OFFSET < pPed->GetPosition().z) + if (pos.z + COP_PED_FIND_Z_OFFSET < pPed->GetPosition().z) continue; ped_handle = CPools::GetPedPool()->GetIndex(pPed); CTheScripts::LastRandomPedId = ped_handle; @@ -9531,11 +9901,11 @@ int8 CRunningScript::ProcessCommands1100To1199(int32 command) StoreParameters(&m_nIp, 1); return 0; } + /* case COMMAND_GET_RANDOM_COP_IN_ZONE: { char zone[KEY_LENGTH_IN_SCRIPT]; strncpy(zone, (const char*)&CTheScripts::ScriptSpace[m_nIp], KEY_LENGTH_IN_SCRIPT); -// TODO(MIAMI): just getting this to compile with new argument int nZone = CTheZones::FindZoneByLabelAndReturnIndex(zone, ZONE_DEFAULT); if (nZone != -1) m_nIp += KEY_LENGTH_IN_SCRIPT; @@ -9563,9 +9933,9 @@ int8 CRunningScript::ProcessCommands1100To1199(int32 command) continue; if (!CTheZones::PointLiesWithinZone(&pPed->GetPosition(), pZone)) continue; - if (pos.z - PED_FIND_Z_OFFSET > pPed->GetPosition().z) + if (pos.z - COP_PED_FIND_Z_OFFSET > pPed->GetPosition().z) continue; - if (pos.z + PED_FIND_Z_OFFSET < pPed->GetPosition().z) + if (pos.z + COP_PED_FIND_Z_OFFSET < pPed->GetPosition().z) continue; ped_handle = CPools::GetPedPool()->GetIndex(pPed); CTheScripts::LastRandomPedId = ped_handle; @@ -9579,6 +9949,7 @@ int8 CRunningScript::ProcessCommands1100To1199(int32 command) StoreParameters(&m_nIp, 1); return 0; } + */ case COMMAND_SET_CHAR_OBJ_FLEE_CAR: { CollectParameters(&m_nIp, 2); @@ -9635,7 +10006,7 @@ int8 CRunningScript::ProcessCommands1100To1199(int32 command) CollectParameters(&m_nIp, 1); CPed* pPed = CWorld::Players[ScriptParams[0]].m_pPed; assert(pPed); - ScriptParams[0] = pPed->m_weapons[pPed->m_currentWeapon].m_eWeaponType; + ScriptParams[0] = pPed->GetWeapon()->m_eWeaponType; StoreParameters(&m_nIp, 1); return 0; } @@ -9644,7 +10015,7 @@ int8 CRunningScript::ProcessCommands1100To1199(int32 command) CollectParameters(&m_nIp, 1); CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]); assert(pPed); - ScriptParams[0] = pPed->m_weapons[pPed->m_currentWeapon].m_eWeaponType; + ScriptParams[0] = pPed->GetWeapon()->m_eWeaponType; StoreParameters(&m_nIp, 1); return 0; } @@ -9665,6 +10036,7 @@ int8 CRunningScript::ProcessCommands1100To1199(int32 command) pVehicle->AutoPilot.m_nTimeTempAction = CTimer::GetTimeInMilliseconds() + ScriptParams[2]; return 0; } + /* case COMMAND_SET_CAR_HANDBRAKE_TURN_RIGHT: { CollectParameters(&m_nIp, 2); @@ -9683,18 +10055,21 @@ int8 CRunningScript::ProcessCommands1100To1199(int32 command) pVehicle->AutoPilot.m_nTimeTempAction = CTimer::GetTimeInMilliseconds() + ScriptParams[1]; return 0; } + */ case COMMAND_IS_CHAR_ON_ANY_BIKE: { CollectParameters(&m_nIp, 1); CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]); assert(pPed); - UpdateCompareFlag(pPed->bInVehicle&& pPed->m_pMyVehicle->m_vehType == VEHICLE_TYPE_BIKE); + UpdateCompareFlag(pPed->bInVehicle&& pPed->m_pMyVehicle->GetVehicleAppearance() == VEHICLE_APPEARANCE_BIKE); return 0; } + /* case COMMAND_LOCATE_SNIPER_BULLET_2D: case COMMAND_LOCATE_SNIPER_BULLET_3D: LocateSniperBulletCommand(command, &m_nIp); return 0; + */ case COMMAND_GET_NUMBER_OF_SEATS_IN_MODEL: CollectParameters(&m_nIp, 1); ScriptParams[0] = CVehicleModelInfo::GetMaximumNumberOfPassengersFromNumberOfDoors(ScriptParams[0]) + 1; @@ -9705,9 +10080,10 @@ int8 CRunningScript::ProcessCommands1100To1199(int32 command) CollectParameters(&m_nIp, 1); CPed* pPed = CWorld::Players[ScriptParams[0]].m_pPed; assert(pPed); - UpdateCompareFlag(pPed->bInVehicle && pPed->m_pMyVehicle->m_vehType == VEHICLE_TYPE_BIKE); + UpdateCompareFlag(pPed->bInVehicle && pPed->m_pMyVehicle->GetVehicleAppearance() == VEHICLE_APPEARANCE_BIKE); return 0; } + /* case COMMAND_IS_CHAR_LYING_DOWN: { CollectParameters(&m_nIp, 1); @@ -9716,6 +10092,7 @@ int8 CRunningScript::ProcessCommands1100To1199(int32 command) UpdateCompareFlag(pPed->bFallenDown); return 0; } + */ case COMMAND_CAN_CHAR_SEE_DEAD_CHAR: { CollectParameters(&m_nIp, 2); @@ -9740,14 +10117,41 @@ int8 CRunningScript::ProcessCommands1100To1199(int32 command) CPed::nThreatReactionRangeMultiplier = *(float*)&ScriptParams[0]; return 0; case COMMAND_SET_CHAR_CEASE_ATTACK_TIMER: + { + CollectParameters(&m_nIp, 2); + CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]); + assert(pPed); + pPed->m_ceaseAttackTimer = ScriptParams[1]; + return 0; + } case COMMAND_GET_REMOTE_CONTROLLED_CAR: + { + CollectParameters(&m_nIp, 1); + CVehicle* pVehicle = CWorld::Players[ScriptParams[0]].m_pRemoteVehicle; + if (pVehicle) + ScriptParams[0] = CPools::GetVehiclePool()->GetIndex(pVehicle); + else + ScriptParams[0] = -1; + StoreParameters(&m_nIp, 1); + return 0; + } case COMMAND_IS_PC_VERSION: - case COMMAND_REPLAY: - case COMMAND_IS_REPLAY_PLAYING: + UpdateCompareFlag(true); + return 0; + //case COMMAND_REPLAY: + //case COMMAND_IS_REPLAY_PLAYING: case COMMAND_IS_MODEL_AVAILABLE: + CollectParameters(&m_nIp, 1); + UpdateCompareFlag(CModelInfo::GetModelInfo(ScriptParams[0]) != nil); + return 0; case COMMAND_SHUT_CHAR_UP: + CollectParameters(&m_nIp, 2); + debug("SHUT_CHAR_UP not implemented"); // TODO(MIAMI) + return 0; case COMMAND_SET_ENABLE_RC_DETONATE: - assert(0); + CollectParameters(&m_nIp, 1); + CVehicle::bDisableRemoteDetonation = !ScriptParams[0]; + return 0; case COMMAND_SET_CAR_RANDOM_ROUTE_SEED: { CollectParameters(&m_nIp, 2); @@ -9757,40 +10161,229 @@ int8 CRunningScript::ProcessCommands1100To1199(int32 command) return 0; } case COMMAND_IS_ANY_PICKUP_AT_COORDS: + { + CollectParameters(&m_nIp, 3); + CVector pos = *(CVector*)&ScriptParams[0]; + CRunningScript::UpdateCompareFlag(CPickups::TestForPickupsInBubble(pos, 0.5f)); + return 0; + } case COMMAND_GET_FIRST_PICKUP_COORDS: case COMMAND_GET_NEXT_PICKUP_COORDS: case COMMAND_REMOVE_ALL_CHAR_WEAPONS: + { + CollectParameters(&m_nIp, 1); + CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]); + assert(pPed); + pPed->ClearWeapons(); + return 0; + } case COMMAND_HAS_PLAYER_GOT_WEAPON: - case COMMAND_HAS_CHAR_GOT_WEAPON: - case COMMAND_IS_PLAYER_FACING_CHAR: + { + CollectParameters(&m_nIp, 2); + CPed* pPed = CWorld::Players[ScriptParams[0]].m_pPed; + assert(pPed); + bool bFound = false; + for (int i = 0; i < TOTAL_WEAPON_SLOTS; i++) { + if (pPed->GetWeapon(i).m_eWeaponType == ScriptParams[1]) { + bFound = true; + break; + } + } + UpdateCompareFlag(bFound); + return 0; + } + //case COMMAND_HAS_CHAR_GOT_WEAPON: + //case COMMAND_IS_PLAYER_FACING_CHAR: case COMMAND_SET_TANK_DETONATE_CARS: + { + CollectParameters(&m_nIp, 2); + CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]); + assert(pVehicle && pVehicle->m_vehType == VEHICLE_TYPE_CAR); + ((CAutomobile*)pVehicle)->bTankDetonateCars = ScriptParams[1]; + return 0; + } case COMMAND_GET_POSITION_OF_ANALOGUE_STICKS: + { + CollectParameters(&m_nIp, 1); + CPad* pPad = CPad::GetPad(ScriptParams[0]); + ScriptParams[0] = pPad->NewState.LeftStickX; + ScriptParams[1] = pPad->NewState.LeftStickY; + ScriptParams[2] = pPad->NewState.RightStickX; + ScriptParams[3] = pPad->NewState.RightStickY; + StoreParameters(&m_nIp, 4); + return 0; + } case COMMAND_IS_CAR_ON_FIRE: + { + CollectParameters(&m_nIp, 1); + CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]); + assert(pVehicle); + bool bOnFire = false; + if (pVehicle->m_pCarFire) + bOnFire = true; + if (pVehicle->m_vehType == VEHICLE_TYPE_CAR && ((CAutomobile*)pVehicle)->Damage.GetEngineStatus() >= ENGINE_STATUS_ON_FIRE) + bOnFire = true; + if (pVehicle->m_fHealth < 250.0f) + bOnFire = true; + UpdateCompareFlag(bOnFire); + return 0; + } case COMMAND_IS_CAR_TYRE_BURST: - case COMMAND_SET_CAR_DRIVE_STRAIGHT_AHEAD: - case COMMAND_SET_CAR_WAIT: - case COMMAND_IS_PLAYER_STANDING_ON_A_VEHICLE: - case COMMAND_IS_PLAYER_FOOT_DOWN: - case COMMAND_IS_CHAR_FOOT_DOWN: + { + CollectParameters(&m_nIp, 2); + CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]); + assert(pVehicle); + bool bIsBurst = false; + if (pVehicle->m_vehType == VEHICLE_APPEARANCE_BIKE) { + assert("IS_CAR_TYPE_BURST not yet implemented for bikes"); + } + else { + CAutomobile* pCar = (CAutomobile*)pVehicle; + if (ScriptParams[1] == 4) { + for (int i = 0; i < 4; i++) { + if (pCar->Damage.GetWheelStatus(i) == WHEEL_STATUS_BURST) + bIsBurst = true; + } + } + else + bIsBurst = pCar->Damage.GetWheelStatus(ScriptParams[1] == WHEEL_STATUS_BURST); + } + UpdateCompareFlag(bIsBurst); + } + //case COMMAND_SET_CAR_DRIVE_STRAIGHT_AHEAD: + //case COMMAND_SET_CAR_WAIT: + //case COMMAND_IS_PLAYER_STANDING_ON_A_VEHICLE: + //case COMMAND_IS_PLAYER_FOOT_DOWN: + //case COMMAND_IS_CHAR_FOOT_DOWN: case COMMAND_INITIALISE_OBJECT_PATH: + // TODO(MIAMI): script path + CollectParameters(&m_nIp, 2); + debug("INITALISE_OBJECT_PATH not yet implemented, skipping\n"); + ScriptParams[0] = 0; + StoreParameters(&m_nIp, 1); + return 0; case COMMAND_START_OBJECT_ON_PATH: + { + CollectParameters(&m_nIp, 2); + debug("START_OBJECT_ON_PATH not yet implemented, skipping\n"); + return 0; + } case COMMAND_SET_OBJECT_PATH_SPEED: + { + CollectParameters(&m_nIp, 2); + debug("SET_OBJECT_PATH_SPEED not yet implemented, skipping\n"); + return 0; + } case COMMAND_SET_OBJECT_PATH_POSITION: - case COMMAND_GET_OBJECT_DISTANCE_ALONG_PATH: + { + CollectParameters(&m_nIp, 2); + debug("SET_OBJECT_PATH_POSITION not yet implemented, skipping\n"); + return 0; + } + //case COMMAND_GET_OBJECT_DISTANCE_ALONG_PATH: case COMMAND_CLEAR_OBJECT_PATH: + { + CollectParameters(&m_nIp, 1); + debug("CLEAR_OBJECT_PATH not yet implemented, skipping\n"); + return 0; + } case COMMAND_HELI_GOTO_COORDS: + { + CollectParameters(&m_nIp, 5); + CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]); + assert(pVehicle && pVehicle->GetVehicleAppearance() == VEHICLE_APPEARANCE_HELI); + ((CAutomobile*)pVehicle)->TellHeliToGoToCoors(*(float*)&ScriptParams[1], *(float*)&ScriptParams[2], *(float*)&ScriptParams[3], ScriptParams[4]); + return 0; + } case COMMAND_IS_INT_VAR_EQUAL_TO_CONSTANT: + { + int32* ptr = GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL); + CollectParameters(&m_nIp, 1); + UpdateCompareFlag(*ptr = ScriptParams[0]); + return 0; + } case COMMAND_IS_INT_LVAR_EQUAL_TO_CONSTANT: + { + int32* ptr = GetPointerToScriptVariable(&m_nIp, VAR_LOCAL); + CollectParameters(&m_nIp, 1); + UpdateCompareFlag(*ptr = ScriptParams[0]); + return 0; + } case COMMAND_GET_DEAD_CHAR_PICKUP_COORDS: + { + CollectParameters(&m_nIp, 1); + CPed *pTarget = CPools::GetPedPool()->GetAt(ScriptParams[0]); + CVector pos; + pTarget->CreateDeadPedPickupCoors(&pos.x, &pos.y, &pos.z); + *(CVector*)&ScriptParams[0] = pos; + StoreParameters(&m_nIp, 3); + return 0; + } case COMMAND_CREATE_PROTECTION_PICKUP: + { + CollectParameters(&m_nIp, 5); + CVector pos = *(CVector*)&ScriptParams[0]; + if (pos.z <= MAP_Z_LOW_LIMIT) + pos.z = CWorld::FindGroundZForCoord(pos.x, pos.y) + PICKUP_PLACEMENT_OFFSET; + ScriptParams[0] = CPickups::GenerateNewOne(pos, MI_PICKUP_REVENUE, PICKUP_ASSET_REVENUE, ScriptParams[3], ScriptParams[4]); + StoreParameters(&m_nIp, 1); + return 0; + } case COMMAND_IS_CHAR_IN_ANY_BOAT: + { + CollectParameters(&m_nIp, 1); + CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]); + assert(pPed); + UpdateCompareFlag(pPed->bInVehicle && pPed->m_pMyVehicle->GetVehicleAppearance() == VEHICLE_APPEARANCE_BOAT); + return 0; + } case COMMAND_IS_PLAYER_IN_ANY_BOAT: + { + CollectParameters(&m_nIp, 1); + CPed* pPed = CWorld::Players[ScriptParams[0]].m_pPed; + assert(pPed); + UpdateCompareFlag(pPed->bInVehicle && pPed->m_pMyVehicle->GetVehicleAppearance() == VEHICLE_APPEARANCE_BIKE); + return 0; + } case COMMAND_IS_CHAR_IN_ANY_HELI: + { + CollectParameters(&m_nIp, 1); + CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]); + assert(pPed); + UpdateCompareFlag(pPed->bInVehicle && pPed->m_pMyVehicle->GetVehicleAppearance() == VEHICLE_APPEARANCE_HELI); + return 0; + } case COMMAND_IS_PLAYER_IN_ANY_HELI: + { + CollectParameters(&m_nIp, 1); + CPed* pPed = CWorld::Players[ScriptParams[0]].m_pPed; + assert(pPed); + UpdateCompareFlag(pPed->bInVehicle && pPed->m_pMyVehicle->GetVehicleAppearance() == VEHICLE_APPEARANCE_HELI); + return 0; + } case COMMAND_IS_CHAR_IN_ANY_PLANE: + { + CollectParameters(&m_nIp, 1); + CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]); + assert(pPed); + UpdateCompareFlag(pPed->bInVehicle && pPed->m_pMyVehicle->GetVehicleAppearance() == VEHICLE_APPEARANCE_PLANE); + return 0; + } case COMMAND_IS_PLAYER_IN_ANY_PLANE: + { + CollectParameters(&m_nIp, 1); + CPed* pPed = CWorld::Players[ScriptParams[0]].m_pPed; + assert(pPed); + UpdateCompareFlag(pPed->bInVehicle && pPed->m_pMyVehicle->GetVehicleAppearance() == VEHICLE_APPEARANCE_HELI); + return 0; + } case COMMAND_IS_CHAR_IN_WATER: - assert(0); + { + CollectParameters(&m_nIp, 1); + CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]); + UpdateCompareFlag(pPed && pPed->bIsInWater); + return 0; + } case COMMAND_SET_VAR_INT_TO_CONSTANT: { int32* ptr = GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL); @@ -9816,17 +10409,89 @@ int8 CRunningScript::ProcessCommands1200To1299(int32 command) { switch (command) { case COMMAND_IS_INT_VAR_GREATER_THAN_CONSTANT: + { + int32* ptr = GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL); + CollectParameters(&m_nIp, 1); + UpdateCompareFlag(*ptr > ScriptParams[0]); + return 0; + } case COMMAND_IS_INT_LVAR_GREATER_THAN_CONSTANT: + { + int32* ptr = GetPointerToScriptVariable(&m_nIp, VAR_LOCAL); + CollectParameters(&m_nIp, 1); + UpdateCompareFlag(*ptr > ScriptParams[0]); + return 0; + } case COMMAND_IS_CONSTANT_GREATER_THAN_INT_VAR: + { + CollectParameters(&m_nIp, 1); + int32* ptr = GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL); + UpdateCompareFlag(ScriptParams[0] > *ptr); + return 0; + } case COMMAND_IS_CONSTANT_GREATER_THAN_INT_LVAR: + { + CollectParameters(&m_nIp, 1); + int32* ptr = GetPointerToScriptVariable(&m_nIp, VAR_LOCAL); + UpdateCompareFlag(ScriptParams[0] > *ptr); + return 0; + } case COMMAND_IS_INT_VAR_GREATER_OR_EQUAL_TO_CONSTANT: + { + int32* ptr = GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL); + CollectParameters(&m_nIp, 1); + UpdateCompareFlag(*ptr >= ScriptParams[0]); + return 0; + } case COMMAND_IS_INT_LVAR_GREATER_OR_EQUAL_TO_CONSTANT: + { + int32* ptr = GetPointerToScriptVariable(&m_nIp, VAR_LOCAL); + CollectParameters(&m_nIp, 1); + UpdateCompareFlag(*ptr >= ScriptParams[0]); + return 0; + } case COMMAND_IS_CONSTANT_GREATER_OR_EQUAL_TO_INT_VAR: + { + CollectParameters(&m_nIp, 1); + int32* ptr = GetPointerToScriptVariable(&m_nIp, VAR_LOCAL); + UpdateCompareFlag(ScriptParams[0] >= *ptr); + return 0; + } case COMMAND_IS_CONSTANT_GREATER_OR_EQUAL_TO_INT_LVAR: + { + CollectParameters(&m_nIp, 1); + int32* ptr = GetPointerToScriptVariable(&m_nIp, VAR_LOCAL); + UpdateCompareFlag(ScriptParams[0] >= *ptr); + return 0; + } case COMMAND_GET_CHAR_WEAPON_IN_SLOT: + { + CollectParameters(&m_nIp, 2); + CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]); + assert(pPed); + ScriptParams[0] = pPed->GetWeapon(ScriptParams[1]).m_eWeaponType; + ScriptParams[1] = pPed->GetWeapon(ScriptParams[1]).m_nAmmoTotal; + ScriptParams[2] = CPickups::ModelForWeapon((eWeaponType)ScriptParams[0]); + StoreParameters(&m_nIp, 3); + } case COMMAND_GET_CLOSEST_STRAIGHT_ROAD: + { + CollectParameters(&m_nIp, 5); + debug("GET_CLOSEST_STRAIGHT_ROAD not implemented!\n"); + for (int i = 0; i < 7; i++) + ScriptParams[i] = 0; + StoreParameters(&m_nIp, 7); // TODO(MIAMI) + } case COMMAND_SET_CAR_FORWARD_SPEED: - assert(0); + { + CollectParameters(&m_nIp, 2); + CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]); + assert(pVehicle); + float speed = *(float*)&ScriptParams[1] / GAME_SPEED_TO_CARAI_SPEED; + pVehicle->SetMoveSpeed(pVehicle->GetForward() * speed); + // TODO(MIAMI): heli hack! + return 0; + } case COMMAND_SET_AREA_VISIBLE: CollectParameters(&m_nIp, 1); CGame::currArea = ScriptParams[0]; @@ -9834,7 +10499,13 @@ int8 CRunningScript::ProcessCommands1200To1299(int32 command) //CStreaming::RemoveBuildingsNotInArea(ScriptParams[0]); return 0; case COMMAND_SET_CUTSCENE_ANIM_TO_LOOP: - assert(0); + { + char key[KEY_LENGTH_IN_SCRIPT]; + CTheScripts::ReadTextLabelFromScript(&m_nIp, key); + m_nIp += KEY_LENGTH_IN_SCRIPT; + debug("SET_CUTSCENE_ANIM_TO_LOOP not implemented yet, skipping\n"); + return 0; + } case COMMAND_MARK_CAR_AS_CONVOY_CAR: { CollectParameters(&m_nIp, 2); @@ -9844,22 +10515,95 @@ int8 CRunningScript::ProcessCommands1200To1299(int32 command) return 0; } case COMMAND_RESET_HAVOC_CAUSED_BY_PLAYER: + { + CollectParameters(&m_nIp, 1); + CWorld::Players[ScriptParams[0]].m_nHavocLevel = 0; + return 0; + } case COMMAND_GET_HAVOC_CAUSED_BY_PLAYER: + { + CollectParameters(&m_nIp, 1); + ScriptParams[0] = CWorld::Players[ScriptParams[0]].m_nHavocLevel; + StoreParameters(&m_nIp, 1); + return 0; + } case COMMAND_CREATE_SCRIPT_ROADBLOCK: + { + CollectParameters(&m_nIp, 6); + debug("CREATE_SCRIPT_ROADBLOCK not implemented\n"); // TODO(MIAMI) + return 0; + } case COMMAND_CLEAR_ALL_SCRIPT_ROADBLOCKS: + { + debug("CLEAR_ALL_SCRIPT_ROADBLOCKS not implemented\n"); // TODO(MIAMI) + return 0; + } case COMMAND_SET_CHAR_OBJ_WALK_TO_CHAR: - case COMMAND_IS_PICKUP_IN_ZONE: + { + CollectParameters(&m_nIp, 2); + CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]); + assert(pPed); + CPed* pTargetPed = CPools::GetPedPool()->GetAt(ScriptParams[1]); + assert(pTargetPed); + pPed->bScriptObjectiveCompleted = false; + pPed->SetObjective(OBJECTIVE_FOLLOW_PED_IN_FORMATION, pPed); + return 0; + } + //case COMMAND_IS_PICKUP_IN_ZONE: case COMMAND_GET_OFFSET_FROM_CHAR_IN_WORLD_COORDS: + { + CollectParameters(&m_nIp, 4); + CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]); + assert(pPed); + CVector result = Multiply3x3(pPed->GetMatrix(), *(CVector*)&ScriptParams[1]) + pPed->GetPosition(); + *(CVector*)&ScriptParams[0] = result; + StoreParameters(&m_nIp, 3); + return 0; + } case COMMAND_HAS_CHAR_BEEN_PHOTOGRAPHED: + { + CollectParameters(&m_nIp, 1); + CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]); + assert(pPed); + bool result = false; + if (pPed->bHasBeenPhotographed) { + result = true; + pPed->bHasBeenPhotographed = false; + } + UpdateCompareFlag(result); + return 0; + } case COMMAND_SET_CHAR_OBJ_AIM_GUN_AT_CHAR: + { + CollectParameters(&m_nIp, 2); + CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]); + assert(pPed); + CPed* pTargetPed = CPools::GetPedPool()->GetAt(ScriptParams[1]); + assert(pTargetPed); + pPed->bScriptObjectiveCompleted = false; + debug("SET_CHAR_OBJ_AIM_GUN_AT_CHAR is not implemented\n"); + //pPed->SetObjective(OBJECTIVE_AIM_GUN_AT_PED, pTargetPed); // TODO(MIAMI) -- when objective is implemented + return 0; + } case COMMAND_SWITCH_SECURITY_CAMERA: - case COMMAND_IS_CHAR_IN_FLYING_VEHICLE: + { + CollectParameters(&m_nIp, 1); + debug("SWITCH_SECURITY_CAMERA is not implemented\n"); // TODO(MIAMI) + return 0; + } + //case COMMAND_IS_CHAR_IN_FLYING_VEHICLE: case COMMAND_IS_PLAYER_IN_FLYING_VEHICLE: - case COMMAND_HAS_SONY_CD_BEEN_READ: - case COMMAND_GET_NUMBER_OF_SONY_CDS_READ: - case COMMAND_ADD_SHORT_RANGE_BLIP_FOR_COORD_OLD: - case COMMAND_ADD_SHORT_RANGE_BLIP_FOR_COORD: - assert(0); + { + CollectParameters(&m_nIp, 1); + CPed* pPed = CWorld::Players[ScriptParams[0]].m_pPed; + assert(pPed); + UpdateCompareFlag(pPed->bInVehicle && (pPed->m_pMyVehicle->GetVehicleAppearance() == VEHICLE_APPEARANCE_HELI || pPed->m_pMyVehicle->GetVehicleAppearance() == VEHICLE_APPEARANCE_PLANE)); + return 0; + } + //case COMMAND_HAS_SONY_CD_BEEN_READ: + //case COMMAND_GET_NUMBER_OF_SONY_CDS_READ: + //case COMMAND_ADD_SHORT_RANGE_BLIP_FOR_COORD_OLD: + //case COMMAND_ADD_SHORT_RANGE_BLIP_FOR_COORD: case COMMAND_ADD_SHORT_RANGE_SPRITE_BLIP_FOR_COORD: { CollectParameters(&m_nIp, 4); @@ -9874,27 +10618,137 @@ int8 CRunningScript::ProcessCommands1200To1299(int32 command) return 0; } case COMMAND_ADD_MONEY_SPENT_ON_CLOTHES: + CollectParameters(&m_nIp, 1); + CStats::MoneySpentOnFashion(ScriptParams[0]); + return 0; + case COMMAND_SET_HELI_ORIENTATION: + { + CollectParameters(&m_nIp, 2); + debug("SET_HELI_ORIENTATION is not implemented\n"); // TODO(MIAMI); + return 0; + } case COMMAND_CLEAR_HELI_ORIENTATION: + { + CollectParameters(&m_nIp, 1); + debug("SET_HELI_ORIENTATION is not implemented\n"); // TODO(MIAMI); + return 0; + } case COMMAND_PLANE_GOTO_COORDS: + { + CollectParameters(&m_nIp, 5); + debug("PLANE_GOTO_COORS is not implemented\n"); // TODO(MIAMI) + return 0; + } case COMMAND_GET_NTH_CLOSEST_CAR_NODE: - case COMMAND_GET_NTH_CLOSEST_CHAR_NODE: + { + CollectParameters(&m_nIp, 4); + debug("GET_NTH_CLOSEST_CAR_NODE is not implemented\n"); // TODO(MIAMI) + ScriptParams[0] = 0; + StoreParameters(&m_nIp, 1); + return 0; + } + //case COMMAND_GET_NTH_CLOSEST_CHAR_NODE: case COMMAND_DRAW_WEAPONSHOP_CORONA: + { + CollectParameters(&m_nIp, 9); + CVector pos = *(CVector*)&ScriptParams[0]; + if (pos.z <= MAP_Z_LOW_LIMIT) + pos.z = CWorld::FindGroundZForCoord(pos.x, pos.y); + CCoronas::RegisterCorona((uintptr)this + m_nIp, ScriptParams[6], ScriptParams[7], ScriptParams[8], 255, pos, *(float*)&ScriptParams[3], + 150.0f, ScriptParams[4], ScriptParams[5], 1, 0, 0, 0.0f, false, 0.2f); + return 0; + } case COMMAND_SET_ENABLE_RC_DETONATE_ON_CONTACT: + { + CollectParameters(&m_nIp, 1); + CVehicle::bDisableRemoteDetonationOnContact = (ScriptParams[0] == 0); + return 0; + } case COMMAND_FREEZE_CHAR_POSITION: + { + CollectParameters(&m_nIp, 2); + CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]); + assert(pPed); + pPed->bIsFrozen = ScriptParams[1]; + return 0; + } case COMMAND_SET_CHAR_DROWNS_IN_WATER: + { + CollectParameters(&m_nIp, 2); + CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]); + assert(pPed); + pPed->bDrownsInWater = ScriptParams[1]; + return 0; + } case COMMAND_SET_OBJECT_RECORDS_COLLISIONS: + { + CollectParameters(&m_nIp, 2); + CObject* pObject = CPools::GetObjectPool()->GetAt(ScriptParams[0]); + assert(pObject); + pObject->bUseCollisionRecords = ScriptParams[1]; + return 0; + } case COMMAND_HAS_OBJECT_COLLIDED_WITH_ANYTHING: + { + CollectParameters(&m_nIp, 1); + CObject* pObject = CPools::GetObjectPool()->GetAt(ScriptParams[0]); + assert(pObject); + UpdateCompareFlag(pObject->m_nCollisionRecords != 0); + return 0; + } case COMMAND_REMOVE_RC_BUGGY: - case COMMAND_HAS_PHOTOGRAPH_BEEN_TAKEN: + { + CWorld::Players[CWorld::PlayerInFocus].BlowUpRCBuggy(false); + return 0; + } + //case COMMAND_HAS_PHOTOGRAPH_BEEN_TAKEN: case COMMAND_GET_CHAR_ARMOUR: - case COMMAND_SET_CHAR_ARMOUR: + { + CollectParameters(&m_nIp, 1); + CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]); + assert(pPed); + ScriptParams[0] = pPed->m_fArmour; + StoreParameters(&m_nIp, 1); + return 0; + } + //case COMMAND_SET_CHAR_ARMOUR: case COMMAND_SET_HELI_STABILISER: + { + CollectParameters(&m_nIp, 2); + CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]); + assert(pVehicle); + pVehicle->bHeliMinimumTilt = ScriptParams[1]; + return 0; + } case COMMAND_SET_CAR_STRAIGHT_LINE_DISTANCE: + { + CollectParameters(&m_nIp, 2); + CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]); + assert(pVehicle); + pVehicle->AutoPilot.m_nSwitchDistance = ScriptParams[1]; + return 0; + } case COMMAND_POP_CAR_BOOT: + { + CollectParameters(&m_nIp, 1); + CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]); + assert(pVehicle); + debug("POP_CAR_BOOT is not implemented\n"); // TODO(MIAMI) + return 0; + } case COMMAND_SHUT_PLAYER_UP: + { + CollectParameters(&m_nIp, 2); + debug("SHUT_PLAYER_UP is not implemented\n"); // TODO(MIAMI) + return 0; + } case COMMAND_SET_PLAYER_MOOD: - assert(0); + { + CollectParameters(&m_nIp, 3); + debug("SET_PLAYER_MOOD is not implemented\n"); // TODO(MIAMI) + return 0; + } case COMMAND_REQUEST_COLLISION: { CollectParameters(&m_nIp, 2); @@ -9906,12 +10760,36 @@ int8 CRunningScript::ProcessCommands1200To1299(int32 command) } case COMMAND_LOCATE_OBJECT_2D: case COMMAND_LOCATE_OBJECT_3D: + LocateObjectCommand(command, &m_nIp); + return 0; case COMMAND_IS_OBJECT_IN_WATER: - case COMMAND_SET_CHAR_OBJ_STEAL_ANY_CAR_EVEN_MISSION_CAR: + { + CollectParameters(&m_nIp, 1); + CObject* pObject = CPools::GetObjectPool()->GetAt(ScriptParams[0]); + assert(pObject); + UpdateCompareFlag(pObject->bIsInWater); + return 0; + } + //case COMMAND_SET_CHAR_OBJ_STEAL_ANY_CAR_EVEN_MISSION_CAR: case COMMAND_IS_OBJECT_IN_AREA_2D: case COMMAND_IS_OBJECT_IN_AREA_3D: + ObjectInAreaCheckCommand(command, &m_nIp); + return 0; case COMMAND_TASK_TOGGLE_DUCK: - assert(0); + { + CollectParameters(&m_nIp, 3); + CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]); + assert(pPed); + if (ScriptParams[1]) { + pPed->bIsDucking = true; + pPed->SetDuck(ScriptParams[2], true); + } + else { + pPed->ClearDuck(true); + pPed->bIsDucking = false; + } + return 0; + } case COMMAND_SET_ZONE_CIVILIAN_CAR_INFO: { char label[12]; @@ -9938,44 +10816,263 @@ int8 CRunningScript::ProcessCommands1200To1299(int32 command) return 0; } case COMMAND_REQUEST_ANIMATION: + { + char key[KEY_LENGTH_IN_SCRIPT]; + CTheScripts::ReadTextLabelFromScript(&m_nIp, key); + m_nIp += KEY_LENGTH_IN_SCRIPT; + CStreaming::RequestAnim(CAnimManager::GetAnimationBlockIndex(key), STREAMFLAGS_SCRIPTOWNED); + return 0; + } case COMMAND_HAS_ANIMATION_LOADED: + { + char key[KEY_LENGTH_IN_SCRIPT]; + CTheScripts::ReadTextLabelFromScript(&m_nIp, key); + m_nIp += KEY_LENGTH_IN_SCRIPT; + UpdateCompareFlag(CAnimManager::GetAnimationBlock(key)->isLoaded); + return 0; + } case COMMAND_REMOVE_ANIMATION: + { + char key[KEY_LENGTH_IN_SCRIPT]; + CTheScripts::ReadTextLabelFromScript(&m_nIp, key); + m_nIp += KEY_LENGTH_IN_SCRIPT; + CStreaming::RemoveAnim(CAnimManager::GetAnimationBlockIndex(key)); + return 0; + } case COMMAND_IS_CHAR_WAITING_FOR_WORLD_COLLISION: + { + CollectParameters(&m_nIp, 1); + CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]); + assert(pPed); + UpdateCompareFlag(pPed->bIsStaticWaitingForCollision); + return 0; + } case COMMAND_IS_CAR_WAITING_FOR_WORLD_COLLISION: + { + CollectParameters(&m_nIp, 1); + CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]); + assert(pVehicle); + UpdateCompareFlag(pVehicle->bIsStaticWaitingForCollision); + return 0; + } case COMMAND_IS_OBJECT_WAITING_FOR_WORLD_COLLISION: + { + CollectParameters(&m_nIp, 1); + CObject* pObject = CPools::GetObjectPool()->GetAt(ScriptParams[0]); + assert(pObject); + UpdateCompareFlag(pObject->bIsStaticWaitingForCollision); + return 0; + } case COMMAND_SET_CHAR_SHUFFLE_INTO_DRIVERS_SEAT: + { + CollectParameters(&m_nIp, 1); + CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]); + assert(pPed); + debug("SET_CHAR_SHUFFLE_INTO_DRIVERS_SEAT is not implemented\n"); + return 0; + } case COMMAND_ATTACH_CHAR_TO_OBJECT: + { + CollectParameters(&m_nIp, 8); + debug("ATTACH_CHAR_TO_OBJECT is not implemented\n"); + return 0; + } case COMMAND_SET_CHAR_AS_PLAYER_FRIEND: - case COMMAND_DISPLAY_NTH_ONSCREEN_COUNTER: + { + CollectParameters(&m_nIp, 3); + CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]); + assert(pPed); + pPed->bIsPlayerFriend = ScriptParams[2]; + return 0; + } + //case COMMAND_DISPLAY_NTH_ONSCREEN_COUNTER: case COMMAND_DISPLAY_NTH_ONSCREEN_COUNTER_WITH_STRING: + { + char onscreen_str[12]; + assert(CTheScripts::ScriptSpace[m_nIp++] == ARGUMENT_GLOBALVAR); + int16 var = CTheScripts::Read2BytesFromScript(&m_nIp); + CollectParameters(&m_nIp, 2); + wchar* text = TheText.Get((char*)&CTheScripts::ScriptSpace[m_nIp]); // ??? + strncpy(onscreen_str, (char*)&CTheScripts::ScriptSpace[m_nIp], KEY_LENGTH_IN_SCRIPT); + m_nIp += KEY_LENGTH_IN_SCRIPT; + CUserDisplay::OnscnTimer.AddCounter(var, ScriptParams[0], onscreen_str, ScriptParams[1] - 1); + return 0; + } case COMMAND_ADD_SET_PIECE: + { + CollectParameters(&m_nIp, 13); + CSetPieces::AddOne(ScriptParams[0], + *(CVector2D*)&ScriptParams[1], *(CVector2D*)&ScriptParams[3], + *(CVector2D*)&ScriptParams[5], *(CVector2D*)&ScriptParams[7], + *(CVector2D*)&ScriptParams[9], *(CVector2D*)&ScriptParams[11]); + return 0; + } case COMMAND_SET_EXTRA_COLOURS: + { + CollectParameters(&m_nIp, 2); + debug("SET_EXTRA_COLOURS not implemented, skipping\n"); + return 0; + } case COMMAND_CLEAR_EXTRA_COLOURS: - case COMMAND_CLOSE_CAR_BOOT: + { + CollectParameters(&m_nIp, 1); + debug("CLEAR_EXTRA_COLOURS not implemented, skipping\n"); + return 0; + } + //case COMMAND_CLOSE_CAR_BOOT: case COMMAND_GET_WHEELIE_STATS: - case COMMAND_DISARM_CHAR: + { + CollectParameters(&m_nIp, 1); + static bool bShowed = false; + if (!bShowed) { + debug("GET_WHEELIE_STATS not implemented\n"); + bShowed = true; + } + for (int i = 0; i < 6; i++) + ScriptParams[i] = 0; + StoreParameters(&m_nIp, 6); + return 0; + } + //case COMMAND_DISARM_CHAR: case COMMAND_BURST_CAR_TYRE: + { + CollectParameters(&m_nIp, 2); + CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]); + if (pVehicle->IsBike()) { + if (ScriptParams[1] == 2) + ScriptParams[1] = 0; + else if (ScriptParams[1] == 3) + ScriptParams[1] = 1; + pVehicle->BurstTyre(ScriptParams[1], true); + } + else { + pVehicle->BurstTyre(ScriptParams[1], true); + } + return 0; + } case COMMAND_IS_CHAR_OBJ_NO_OBJ: + { + CollectParameters(&m_nIp, 1); + CollectParameters(&m_nIp, 3); + CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]); + assert(pPed); + UpdateCompareFlag(pPed->m_prevObjective == OBJECTIVE_NONE && pPed->m_objective == OBJECTIVE_NONE); + return 0; + } case COMMAND_IS_PLAYER_WEARING: + { + CollectParameters(&m_nIp, 1); + char key[12]; + CTheScripts::ReadTextLabelFromScript(&m_nIp, key); + m_nIp += KEY_LENGTH_IN_SCRIPT; + for (int i = 0; i < KEY_LENGTH_IN_SCRIPT; i++) + key[i] = tolower(key[i]); + CPed* pPed = CWorld::Players[ScriptParams[0]].m_pPed; + assert(pPed); + UpdateCompareFlag(strcmp(key, CModelInfo::GetModelInfo(pPed->GetModelIndex())->GetName()) == 0); + return 0; + } case COMMAND_SET_PLAYER_CAN_DO_DRIVE_BY: + { + CollectParameters(&m_nIp, 2); + CPlayerInfo* pPlayerInfo = &CWorld::Players[ScriptParams[0]]; + pPlayerInfo->m_bDriveByAllowed = ScriptParams[1]; + return 0; + } case COMMAND_SET_CHAR_OBJ_SPRINT_TO_COORD: + { + CollectParameters(&m_nIp, 3); + CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]); + assert(pPed); + CVector pos; + pos.x = *(float*)&ScriptParams[1]; + pos.y = *(float*)&ScriptParams[2]; + pos.z = CWorld::FindGroundZForCoord(pos.x, pos.y); + pPed->bScriptObjectiveCompleted = false; + debug("SET_CHAR_OBJ_SPRINT_TO_COORD is not implemented\n"); + //pPed->SetObjective(OBJECTIVE_SPRINT_TO_COORD, pos); // TODO(MIAMI) -- when objective is implemented + return 0; + } case COMMAND_CREATE_SWAT_ROPE: - case COMMAND_SET_FIRST_PERSON_CONTROL_CAMERA: - case COMMAND_GET_NEAREST_TYRE_TO_POINT: + { + CollectParameters(&m_nIp, 3); + debug("SET_CHAR_OBJ_SPRINT_TO_COORD is not implemented\n"); + return 0; + } + //case COMMAND_SET_FIRST_PERSON_CONTROL_CAMERA: + //case COMMAND_GET_NEAREST_TYRE_TO_POINT: case COMMAND_SET_CAR_MODEL_COMPONENTS: + { + CollectParameters(&m_nIp, 3); + CVehicleModelInfo::SetComponentsToUse(ScriptParams[1], ScriptParams[2]); + return 0; + } case COMMAND_SWITCH_LIFT_CAMERA: + { + CollectParameters(&m_nIp, 1); + debug("SWITCH_LIFT_CAMERA is not implemented\n"); // TODO(MIAMI) + return 0; + } case COMMAND_CLOSE_ALL_CAR_DOORS: + { + CollectParameters(&m_nIp, 1); + debug("CLOSE_ALL_CAR_DOORS is not implemented\n"); // TODO(MIAMI) + return 0; + } case COMMAND_GET_DISTANCE_BETWEEN_COORDS_2D: + { + CollectParameters(&m_nIp, 4); + *(float*)&ScriptParams[0] = (*(CVector2D*)&ScriptParams[0] - *(CVector2D*)&ScriptParams[2]).Magnitude(); + StoreParameters(&m_nIp, 1); + return 0; + } case COMMAND_GET_DISTANCE_BETWEEN_COORDS_3D: + { + CollectParameters(&m_nIp, 6); + *(float*)&ScriptParams[0] = (*(CVector*)&ScriptParams[0] - *(CVector*)&ScriptParams[3]).Magnitude(); + StoreParameters(&m_nIp, 1); + return 0; + } case COMMAND_POP_CAR_BOOT_USING_PHYSICS: - case COMMAND_SET_FIRST_PERSON_WEAPON_CAMERA: + { + CollectParameters(&m_nIp, 1); + debug("POP_CAR_BOOT_USING_PHYSICS is not implemented\n"); // TODO(MIAMI) + return 0; + } + //case COMMAND_SET_FIRST_PERSON_WEAPON_CAMERA: case COMMAND_IS_CHAR_LEAVING_VEHICLE_TO_DIE: + { + CollectParameters(&m_nIp, 1); + CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]); + assert(pPed); + UpdateCompareFlag(pPed->m_objective == OBJECTIVE_LEAVE_CAR_AND_DIE); + return 0; + } case COMMAND_SORT_OUT_OBJECT_COLLISION_WITH_CAR: - case COMMAND_GET_MAX_WANTED_LEVEL: + { + CollectParameters(&m_nIp, 2); + CObject* pObject = CPools::GetObjectPool()->GetAt(ScriptParams[0]); + assert(pObject); + pObject->m_pCollidingEntity = CPools::GetVehiclePool()->GetAt(ScriptParams[1]); + return 0; + } + //case COMMAND_GET_MAX_WANTED_LEVEL: case COMMAND_IS_CHAR_WANDER_PATH_CLEAR: - case COMMAND_PRINT_HELP_WITH_NUMBER: + { + CollectParameters(&m_nIp, 5); + CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]); + assert(pPed); + UpdateCompareFlag(CWorld::IsWanderPathClear(pPed->GetPosition(), *(CVector*)&ScriptParams[0], *(float*)&ScriptParams[3], 4)); + return 0; + } + //case COMMAND_PRINT_HELP_WITH_NUMBER: case COMMAND_PRINT_HELP_FOREVER: - case COMMAND_PRINT_HELP_FOREVER_WITH_NUMBER: + { + wchar* text = CTheScripts::GetTextByKeyFromScript(&m_nIp); + CHud::SetHelpMessage(text, false); // TODO(MIAMI): third param is true + return 0; + } + //case COMMAND_PRINT_HELP_FOREVER_WITH_NUMBER: default: assert(0); } @@ -9986,8 +11083,21 @@ int8 CRunningScript::ProcessCommands1300To1399(int32 command) { switch (command) { case COMMAND_SET_CHAR_CAN_BE_DAMAGED_BY_MEMBERS_OF_GANG: + { + CollectParameters(&m_nIp, 3); + CPed* pTarget = CPools::GetPedPool()->GetAt(ScriptParams[0]); + assert(pTarget); + uint8 flag = 1 << (uint8)ScriptParams[1]; + if (ScriptParams[2]) + pTarget->m_gangFlags |= flag; + else + pTarget->m_gangFlags &= ~flag; + + return 0; + } case COMMAND_LOAD_AND_LAUNCH_MISSION_EXCLUSIVE: - case COMMAND_IS_MISSION_AUDIO_PLAYING: + return 0; + //case COMMAND_IS_MISSION_AUDIO_PLAYING: case COMMAND_CREATE_LOCKED_PROPERTY_PICKUP: { CollectParameters(&m_nIp, 3); @@ -10015,92 +11125,523 @@ int8 CRunningScript::ProcessCommands1300To1399(int32 command) return 0; } case COMMAND_FREEZE_CAR_POSITION: + { + CollectParameters(&m_nIp, 2); + CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]); + assert(pVehicle); + pVehicle->bIsFrozen = ScriptParams[1]; + return 0; + } case COMMAND_HAS_CHAR_BEEN_DAMAGED_BY_CHAR: - case COMMAND_HAS_CHAR_BEEN_DAMAGED_BY_CAR: - case COMMAND_HAS_CAR_BEEN_DAMAGED_BY_CHAR: - case COMMAND_HAS_CAR_BEEN_DAMAGED_BY_CAR: - case COMMAND_GET_RADIO_CHANNEL: - case COMMAND_DISPLAY_TEXT_WITH_3_NUMBERS: - case COMMAND_IS_CAR_DROWNING_IN_WATER: + { + CollectParameters(&m_nIp, 2); + CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]); + CPed* pTestedPed = CPools::GetPedPool()->GetAt(ScriptParams[1]); + bool result = false; + if (pPed) { + if (pPed->m_lastDamEntity) { + if (pPed->m_lastDamEntity == pTestedPed) + result = true; + if (pTestedPed->bInVehicle && pPed->m_lastDamEntity == pTestedPed->m_pMyVehicle) + result = true; + } + }else + debug("HAS_CHAR_BEEN_DAMAGED_BY_CHAR - First character doesn't exist\n"); + UpdateCompareFlag(result); + return 0; + } + //case COMMAND_HAS_CHAR_BEEN_DAMAGED_BY_CAR: + //case COMMAND_HAS_CAR_BEEN_DAMAGED_BY_CHAR: + //case COMMAND_HAS_CAR_BEEN_DAMAGED_BY_CAR: + //case COMMAND_GET_RADIO_CHANNEL: + //case COMMAND_DISPLAY_TEXT_WITH_3_NUMBERS: + //case COMMAND_IS_CAR_DROWNING_IN_WATER: case COMMAND_IS_CHAR_DROWNING_IN_WATER: + { + CollectParameters(&m_nIp, 1); + CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]); + UpdateCompareFlag(pPed && pPed->bIsDrowning); + return 0; + } case COMMAND_DISABLE_CUTSCENE_SHADOWS: + { + debug("DISABLE_CUTSCENE_SHADOWS not implemented, skipping\n"); // TODO(MIAMI) + return 0; + } case COMMAND_HAS_GLASS_BEEN_SHATTERED_NEARBY: + { + CollectParameters(&m_nIp, 3); + static bool bShowed = false; + if (!bShowed) { + debug("HAS_GLASS_BEEN_SHATTERED_NEARBY not implemented, default to TRUE\n"); // TODO(MIAMI) + bShowed = true; + } + UpdateCompareFlag(true); + return 0; + } case COMMAND_ATTACH_CUTSCENE_OBJECT_TO_BONE: + { + CollectParameters(&m_nIp, 3); + debug("ATTACH_CUTSCENE_OBJECT_TO_BONE not implemented, skipping\n"); // TODO(MIAMI) + return 0; + } case COMMAND_ATTACH_CUTSCENE_OBJECT_TO_COMPONENT: + { + CollectParameters(&m_nIp, 2); + debug("ATTACH_CUTSCENE_OBJECT_TO_COMPONENT not implemented, skipping\n"); // TODO(MIAMI) + return 0; + } case COMMAND_SET_CHAR_STAY_IN_CAR_WHEN_JACKED: - case COMMAND_IS_MISSION_AUDIO_LOADING: + { + CollectParameters(&m_nIp, 2); + CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]); + assert(pPed); + pPed->bStayInCarOnJack = ScriptParams[1]; + return 0; + } + //case COMMAND_IS_MISSION_AUDIO_LOADING: case COMMAND_ADD_MONEY_SPENT_ON_WEAPONS: + CollectParameters(&m_nIp, 1); + debug("ADD_MONEY_SPENT_ON_WEAPON not implemented\n"); // TODO(MIAMI) + return 0; case COMMAND_ADD_MONEY_SPENT_ON_PROPERTY: - case COMMAND_ADD_MONEY_SPENT_ON_AUTO_PAINTING: + CollectParameters(&m_nIp, 1); + debug("ADD_MONEY_SPENT_ON_PROPERTY not implemented\n"); // TODO(MIAMI) + return 0; + //case COMMAND_ADD_MONEY_SPENT_ON_AUTO_PAINTING: case COMMAND_SET_CHAR_ANSWERING_MOBILE: + { + CollectParameters(&m_nIp, 2); + debug("SET_CHAR_ANSWERING_MOBILE not implemented\n"); // TODO(MIAMI) + return 0; + } case COMMAND_SET_PLAYER_DRUNKENNESS: - case COMMAND_GET_PLAYER_DRUNKENNESS: - case COMMAND_SET_PLAYER_DRUG_LEVEL: - case COMMAND_GET_PLAYER_DRUG_LEVEL: - case COMMAND_ADD_LOAN_SHARK_VISITS: + { + CollectParameters(&m_nIp, 2); + debug("SET_PLAYER_DRUNKENNESS not implemented\n"); // TODO(MIAMI) + return 0; + } + //case COMMAND_GET_PLAYER_DRUNKENNESS: + //case COMMAND_SET_PLAYER_DRUG_LEVEL: + //case COMMAND_GET_PLAYER_DRUG_LEVEL: + //case COMMAND_ADD_LOAN_SHARK_VISITS: case COMMAND_ADD_STORES_KNOCKED_OFF: - case COMMAND_ADD_MOVIE_STUNTS: + CollectParameters(&m_nIp, 1); + debug("ADD_STORES_KNOCKED_OFF not implemented\n"); // TODO(MIAMI) + return 0; + //case COMMAND_ADD_MOVIE_STUNTS: case COMMAND_ADD_NUMBER_OF_ASSASSINATIONS: + CollectParameters(&m_nIp, 1); + debug("ADD_NUMBER_OF_ASSASSINATIONS not implemented\n"); // TODO(MIAMI) + return 0; case COMMAND_ADD_PIZZAS_DELIVERED: - case COMMAND_ADD_GARBAGE_PICKUPS: + CollectParameters(&m_nIp, 1); + debug("ADD_PIZZAS_DELIVERED not implemented\n"); // TODO(MIAMI) + return 0; + //case COMMAND_ADD_GARBAGE_PICKUPS: case COMMAND_ADD_ICE_CREAMS_SOLD: - case COMMAND_SET_TOP_SHOOTING_RANGE_SCORE: - case COMMAND_ADD_SHOOTING_RANGE_RANK: - case COMMAND_ADD_MONEY_SPENT_ON_GAMBLING: - case COMMAND_ADD_MONEY_WON_ON_GAMBLING: - case COMMAND_SET_LARGEST_GAMBLING_WIN: + CollectParameters(&m_nIp, 1); + debug("ADD_ICE_CREAMS_SOLD not implemented\n"); // TODO(MIAMI) + return 0; + //case COMMAND_SET_TOP_SHOOTING_RANGE_SCORE: + //case COMMAND_ADD_SHOOTING_RANGE_RANK: + //case COMMAND_ADD_MONEY_SPENT_ON_GAMBLING: + //case COMMAND_ADD_MONEY_WON_ON_GAMBLING: + //case COMMAND_SET_LARGEST_GAMBLING_WIN: case COMMAND_SET_CHAR_IN_PLAYERS_GROUP_CAN_FIGHT: + { + CollectParameters(&m_nIp, 2); + CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]); + assert(pPed); + pPed->bDontFight = !ScriptParams[1]; + return 0; + } case COMMAND_CLEAR_CHAR_WAIT_STATE: + { + CollectParameters(&m_nIp, 1); + CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]); + assert(pPed); + pPed->ClearWaitState(); + return 0; + } case COMMAND_GET_RANDOM_CAR_OF_TYPE_IN_AREA_NO_SAVE: + { + CollectParameters(&m_nIp, 5); + int handle = -1; + uint32 i = CPools::GetVehiclePool()->GetSize(); + float infX = *(float*)&ScriptParams[0]; + float infY = *(float*)&ScriptParams[1]; + float supX = *(float*)&ScriptParams[2]; + float supY = *(float*)&ScriptParams[3]; + while (i--) { + CVehicle* pVehicle = CPools::GetVehiclePool()->GetSlot(i); + if (!pVehicle) + continue; + if (pVehicle->GetVehicleAppearance() != VEHICLE_APPEARANCE_CAR && pVehicle->GetVehicleAppearance() != VEHICLE_APPEARANCE_BIKE) + continue; + if (ScriptParams[4] != pVehicle->GetModelIndex() && ScriptParams[4] >= 0) + continue; + if (pVehicle->VehicleCreatedBy != RANDOM_VEHICLE) + continue; + if (!pVehicle->IsWithinArea(infX, infY, supX, supY)) + continue; + handle = CPools::GetVehiclePool()->GetIndex(pVehicle); + } + ScriptParams[0] = handle; + StoreParameters(&m_nIp, 1); + return 0; + } case COMMAND_SET_CAN_BURST_CAR_TYRES: + { + CollectParameters(&m_nIp, 2); + CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]); + assert(pVehicle); + pVehicle->bTyresDontBurst = !ScriptParams[1]; + return 0; + } case COMMAND_SET_PLAYER_AUTO_AIM: + { + CollectParameters(&m_nIp, 2); + CPed* pPed = CWorld::Players[ScriptParams[0]].m_pPed; + assert(pPed); + pPed->bDoomAim = ScriptParams[1]; + } case COMMAND_FIRE_HUNTER_GUN: + { + CollectParameters(&m_nIp, 1); + debug("FIRE_HUNTER_GUN is not implemented, skipping\n"); // TODO(MIAMI) + return 0; + } case COMMAND_SET_PROPERTY_AS_OWNED: + CollectParameters(&m_nIp, 1); + debug("SET_PROPERTY_AS_OWNED not implemented\n"); // TODO(MIAMI) + return 0; case COMMAND_ADD_BLOOD_RING_KILLS: + CollectParameters(&m_nIp, 1); + debug("ADD_BLOOD_RING_KILLS not implemented\n"); // TODO(MIAMI) + return 0; case COMMAND_SET_LONGEST_TIME_IN_BLOOD_RING: + CollectParameters(&m_nIp, 1); + debug("SET_LONGEST_TIME_IN_BLOOD_RING not implemented\n"); // TODO(MIAMI) + return 0; case COMMAND_REMOVE_EVERYTHING_FOR_HUGE_CUTSCENE: + { + debug("REMOVE_EVERYTHING_FOR_HUGE_CUTSCENE not implemented, skipping\n"); + return 0; + } case COMMAND_IS_PLAYER_TOUCHING_VEHICLE: - case COMMAND_IS_CHAR_TOUCHING_VEHICLE: + { + CollectParameters(&m_nIp, 2); + CPed* pPed = CWorld::Players[ScriptParams[0]].m_pPed; + assert(pPed); + CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[1]); + CPhysical* pTestedEntity = pPed; + if (pPed->bInVehicle && pPed->m_pMyVehicle) + pTestedEntity = pPed->m_pMyVehicle; + UpdateCompareFlag(pTestedEntity->GetHasCollidedWith(pVehicle)); + return 0; + } + //case COMMAND_IS_CHAR_TOUCHING_VEHICLE: case COMMAND_CHECK_FOR_PED_MODEL_AROUND_PLAYER: + { + CollectParameters(&m_nIp, 6); + CVector d1 = CWorld::Players[ScriptParams[0]].GetPos() - *(CVector*)&ScriptParams[1]; + CVector d2 = CWorld::Players[ScriptParams[0]].GetPos() + *(CVector*)&ScriptParams[1]; + int i = CPools::GetPedPool()->GetSize(); + bool result = false; + while (i--) { + CPed* pPed = CPools::GetPedPool()->GetSlot(i); + if (!pPed) + continue; + if (ScriptParams[4] != pPed->GetModelIndex() && ScriptParams[5] != pPed->GetModelIndex()) + continue; + if (pPed->IsWithinArea(d1.x, d1.y, d1.z, d2.x, d2.y, d2.z)) + result = true; + } + UpdateCompareFlag(result); + return 0; + } case COMMAND_CLEAR_CHAR_FOLLOW_PATH: + { + CollectParameters(&m_nIp, 2); + CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]); + assert(pPed); + if (pPed->GetPedState() == PED_FOLLOW_PATH) { + pPed->RestorePreviousState(); + pPed->ClearFollowPath(); + } + return 0; + } case COMMAND_SET_CHAR_CAN_BE_SHOT_IN_VEHICLE: + { + CollectParameters(&m_nIp, 2); + CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]); + assert(pPed); + pPed->bCanBeShotInVehicle = ScriptParams[1]; + return 0; + } case COMMAND_ATTACH_CUTSCENE_OBJECT_TO_VEHICLE: + { + CollectParameters(&m_nIp, 2); + debug("ATTACH_CUTSCENE_OBJECT_TO_VEHICLE not implemented\n"); // TODO(MIAMI) + return 0; + } case COMMAND_LOAD_MISSION_TEXT: + { + char key[8]; + CTheScripts::ReadTextLabelFromScript(&m_nIp, key); + m_nIp += KEY_LENGTH_IN_SCRIPT; + TheText.LoadMissionText(key); + return 0; + } case COMMAND_SET_TONIGHTS_EVENT: + { + CollectParameters(&m_nIp, 1); + debug("skipping SET_TONIGHTS_EVENT\n"); // TODO(MIAMI) + return 0; + } case COMMAND_CLEAR_CHAR_LAST_DAMAGE_ENTITY: - case COMMAND_CLEAR_CAR_LAST_DAMAGE_ENTITY: + { + CollectParameters(&m_nIp, 1); + CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]); + if (pPed) + pPed->m_lastDamEntity = nil; + else + debug("CLEAR_CHAR_LAST_DAMAGE_ENTITY - Character doesn't exist\n"); + return 0; + } + //case COMMAND_CLEAR_CAR_LAST_DAMAGE_ENTITY: case COMMAND_FREEZE_OBJECT_POSITION: + { + CollectParameters(&m_nIp, 2); + CObject* pObject = CPools::GetObjectPool()->GetAt(ScriptParams[0]); + assert(pObject); + pObject->bIsFrozen = ScriptParams[1]; + return 0; + } case COMMAND_SET_PLAYER_HAS_MET_DEBBIE_HARRY: + { + CollectParameters(&m_nIp, 1); + CTheScripts::bPlayerHasMetDebbieHarry = ScriptParams[0]; + return 0; + } case COMMAND_SET_RIOT_INTENSITY: - case COMMAND_IS_CAR_IN_ANGLED_AREA_2D: - case COMMAND_IS_CAR_IN_ANGLED_AREA_3D: - case COMMAND_REMOVE_WEAPON_FROM_CHAR: + { + CollectParameters(&m_nIp, 1); + CTheScripts::RiotIntensity = ScriptParams[0]; + return 0; + } + //case COMMAND_IS_CAR_IN_ANGLED_AREA_2D: + //case COMMAND_IS_CAR_IN_ANGLED_AREA_3D: + //case COMMAND_REMOVE_WEAPON_FROM_CHAR: case COMMAND_SET_UP_TAXI_SHORTCUT: + { + CollectParameters(&m_nIp, 8); + debug("SET_UP_TAXI_SHORTCUT is not implemented\n"); // TODO(MIAMI) + return 0; + } case COMMAND_CLEAR_TAXI_SHORTCUT: - case COMMAND_SET_CHAR_OBJ_GOTO_CAR_ON_FOOT: - case COMMAND_GET_CLOSEST_WATER_NODE: + debug("CLEAR_TAXI_SHORTCUT is not implemented\n"); // TODO(MIAMI) + return 0; + //case COMMAND_SET_CHAR_OBJ_GOTO_CAR_ON_FOOT: + //case COMMAND_GET_CLOSEST_WATER_NODE: case COMMAND_ADD_PORN_LEAFLET_TO_RUBBISH: + debug("ADD_PORN_LEAFLET_TO_RUBBISH is not implemented\n"); // TODO(MIAMI) + return 0; case COMMAND_CREATE_CLOTHES_PICKUP: - case COMMAND_CHANGE_BLIP_THRESHOLD: + { + CollectParameters(&m_nIp, 4); + CVector pos = *(CVector*)&ScriptParams[0]; + if (pos.z <= MAP_Z_LOW_LIMIT) + pos.z = CWorld::FindGroundZForCoord(pos.x, pos.y) + PICKUP_PLACEMENT_OFFSET; + CPickups::GetActualPickupIndex(CollectNextParameterWithoutIncreasingPC(m_nIp)); + ScriptParams[0] = CPickups::GenerateNewOne(pos, MI_PICKUP_CLOTHES, PICKUP_ON_STREET, ScriptParams[3]); + StoreParameters(&m_nIp, 1); + return 0; + } + //case COMMAND_CHANGE_BLIP_THRESHOLD: case COMMAND_MAKE_PLAYER_FIRE_PROOF: + { + CollectParameters(&m_nIp, 2); + CPlayerInfo* pPlayerInfo = &CWorld::Players[ScriptParams[0]]; + pPlayerInfo->m_bFireproof = ScriptParams[1]; + return 0; + } case COMMAND_INCREASE_PLAYER_MAX_HEALTH: + { + CollectParameters(&m_nIp, 2); + CPlayerInfo* pPlayerInfo = &CWorld::Players[ScriptParams[0]]; + pPlayerInfo->m_nMaxHealth += ScriptParams[1]; + pPlayerInfo->m_pPed->m_fHealth = pPlayerInfo->m_nMaxHealth; + return 0; + } case COMMAND_INCREASE_PLAYER_MAX_ARMOUR: + { + CollectParameters(&m_nIp, 2); + CPlayerInfo* pPlayerInfo = &CWorld::Players[ScriptParams[0]]; + pPlayerInfo->m_nMaxArmour += ScriptParams[1]; + pPlayerInfo->m_pPed->m_fArmour = pPlayerInfo->m_nMaxArmour; + return 0; + } case COMMAND_CREATE_RANDOM_CHAR_AS_DRIVER: + { + CollectParameters(&m_nIp, 1); + CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]); + CPed* pPed = CPopulation::AddPedInCar(pVehicle, true); + pPed->CharCreatedBy = MISSION_CHAR; + pPed->bRespondsToThreats = false; + pPed->bAllowMedicsToReviveMe = false; + pPed->bIsPlayerFriend = false; + if (pVehicle->bIsBus) + pPed->bRenderPedInCar = false; + pPed->SetPosition(pVehicle->GetPosition()); + pPed->SetOrientation(0.0f, 0.0f, 0.0f); + pPed->SetPedState(PED_DRIVING); + pPed->m_pMyVehicle = pVehicle; + pPed->m_pMyVehicle->RegisterReference((CEntity**)&pPed->m_pMyVehicle); + pVehicle->pDriver = pPed; + pVehicle->pDriver->RegisterReference((CEntity**)&pVehicle->pDriver); + pPed->bInVehicle = true; + pVehicle->SetStatus(STATUS_PHYSICS); + if (pVehicle->m_vehType == VEHICLE_TYPE_BOAT) + pVehicle->AutoPilot.m_nCarMission = MISSION_CRUISE; + pVehicle->bEngineOn = true; + pVehicle->m_nZoneLevel = CTheZones::GetLevelFromPosition(&pVehicle->GetPosition()); + CPopulation::ms_nTotalMissionPeds++; + ScriptParams[0] = CPools::GetPedPool()->GetIndex(pPed); + StoreParameters(&m_nIp, 1); + if (m_bIsMissionScript) + CTheScripts::MissionCleanup.AddEntityToList(ScriptParams[0], CLEANUP_CHAR); + return 0; + } case COMMAND_CREATE_RANDOM_CHAR_AS_PASSENGER: + { + CollectParameters(&m_nIp, 2); + CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]); + CPed* pPed = CPopulation::AddPedInCar(pVehicle, false); + pPed->CharCreatedBy = MISSION_CHAR; + pPed->bRespondsToThreats = false; + pPed->bAllowMedicsToReviveMe = false; + pPed->bIsPlayerFriend = false; + if (pVehicle->bIsBus) + pPed->bRenderPedInCar = false; + pPed->SetPosition(pVehicle->GetPosition()); + pPed->SetOrientation(0.0f, 0.0f, 0.0f); + CPopulation::ms_nTotalMissionPeds++; + pVehicle->m_nZoneLevel = CTheZones::GetLevelFromPosition(&pVehicle->GetPosition()); + if (ScriptParams[1] >= 0) + pVehicle->AddPassenger(pPed, ScriptParams[1]); + else + pVehicle->AddPassenger(pPed); + + pPed->m_pMyVehicle = pVehicle; + pPed->m_pMyVehicle->RegisterReference((CEntity**)&pPed->m_pMyVehicle); + pPed->bInVehicle = true; + pPed->SetPedState(PED_DRIVING); + ScriptParams[0] = CPools::GetPedPool()->GetIndex(pPed); + StoreParameters(&m_nIp, 1); + if (m_bIsMissionScript) + CTheScripts::MissionCleanup.AddEntityToList(ScriptParams[0], CLEANUP_CHAR); + return 0; + } case COMMAND_SET_CHAR_IGNORE_THREATS_BEHIND_OBJECTS: + { + CollectParameters(&m_nIp, 2); + CPed* pPed = CWorld::Players[ScriptParams[0]].m_pPed; + assert(pPed); + pPed->bIgnoreThreatsBehindObjects = ScriptParams[1]; + return 0; + } case COMMAND_ENSURE_PLAYER_HAS_DRIVE_BY_WEAPON: + { + CollectParameters(&m_nIp, 2); + CPed* pPed = CWorld::Players[ScriptParams[0]].m_pPed; + assert(pPed); + if (pPed->bInVehicle) { + if (pPed->GetWeapon(5).m_eWeaponType) { // TODO(MIAMI): enum + if (pPed->GetWeapon(5).m_nAmmoTotal < ScriptParams[1]) + pPed->SetAmmo(pPed->GetWeapon(5).m_eWeaponType, ScriptParams[1]); + } + else { + pPed->GiveWeapon(WEAPONTYPE_UZI, ScriptParams[1], true); + if (pPed->m_storedWeapon == WEAPONTYPE_UNIDENTIFIED) + pPed->m_storedWeapon = pPed->GetWeapon()->m_eWeaponType; + pPed->SetCurrentWeapon(WEAPONTYPE_UZI); + } + } + return 0; + } case COMMAND_MAKE_HELI_COME_CRASHING_DOWN: + { + CollectParameters(&m_nIp, 1); + debug("MAKE_HELI_COME_CRASHING_DOWN is not implemented\n"); + return 0; + } case COMMAND_ADD_EXPLOSION_NO_SOUND: + { + CollectParameters(&m_nIp, 4); + CExplosion::AddExplosion(nil, nil, (eExplosionType)ScriptParams[3], *(CVector*)&ScriptParams[0], 0); // TODO(MIAMI): last arg is 0 + return 0; + } case COMMAND_SET_OBJECT_AREA_VISIBLE: - case COMMAND_WAS_VEHICLE_EVER_POLICE: + { + CollectParameters(&m_nIp, 2); + CObject* pObject = CPools::GetObjectPool()->GetAt(ScriptParams[0]); + assert(pObject); + pObject->m_area = ScriptParams[1]; + return 0; + } + //case COMMAND_WAS_VEHICLE_EVER_POLICE: case COMMAND_SET_CHAR_NEVER_TARGETTED: + { + CollectParameters(&m_nIp, 2); + CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]); + assert(pPed); + pPed->bNeverEverTargetThisPed = ScriptParams[1]; + return 0; + } case COMMAND_LOAD_UNCOMPRESSED_ANIM: + { + char key[KEY_LENGTH_IN_SCRIPT]; + CTheScripts::ReadTextLabelFromScript(&m_nIp, key); + m_nIp += KEY_LENGTH_IN_SCRIPT; + debug("LOAD_UNCOMPRESSED_ANIM not implemented\n"); // TODO(MIAMI) + return 0; + } case COMMAND_WAS_CUTSCENE_SKIPPED: + { + static bool bShowed = false; + if (!bShowed) { + debug("COMMAND_WAS_CUTSCENE_SKIPPED not implemented, default to TRUE\n"); + bShowed = true; + } + UpdateCompareFlag(true); + return 0; + } case COMMAND_SET_CHAR_CROUCH_WHEN_THREATENED: + { + CollectParameters(&m_nIp, 2); + CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]); + debug("SET_CHAR_CROUCH_WHEN_THREATENED not implemented, skipping\n"); + return 0; + } case COMMAND_IS_CHAR_IN_ANY_POLICE_VEHICLE: + { + CollectParameters(&m_nIp, 1); + static bool bShowed = false; + if (!bShowed) { + debug("IS_CHAR_IN_ANY_POLICE_VEHICLE not implemented, default to FALSE\n"); + bShowed = true; + } + UpdateCompareFlag(false); + return 0; + } case COMMAND_DOES_CHAR_EXIST: - case COMMAND_DOES_VEHICLE_EXIST: - case COMMAND_ADD_SHORT_RANGE_BLIP_FOR_CONTACT_POINT: + CollectParameters(&m_nIp, 1); + UpdateCompareFlag(CPools::GetPedPool()->GetAt(ScriptParams[0]) != 0); + return 0; + //case COMMAND_DOES_VEHICLE_EXIST: + //case COMMAND_ADD_SHORT_RANGE_BLIP_FOR_CONTACT_POINT: case COMMAND_ADD_SHORT_RANGE_SPRITE_BLIP_FOR_CONTACT_POINT: { CollectParameters(&m_nIp, 4); @@ -10115,12 +11656,55 @@ int8 CRunningScript::ProcessCommands1300To1399(int32 command) return 0; } case COMMAND_IS_CHAR_STUCK: + { + CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]); + assert(pPed); + UpdateCompareFlag(pPed->m_nWaitState == WAITSTATE_STUCK); + } case COMMAND_SET_ALL_TAXIS_HAVE_NITRO: + { + CollectParameters(&m_nIp, 1); + debug("SET_ALL_TAXIS_HAVE_NITRO is not implemented\n"); // TODO(MIAMI) + return 0; + } case COMMAND_SET_CHAR_STOP_SHOOT_DONT_SEEK_ENTITY: + { + CollectParameters(&m_nIp, 2); + CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]); + assert(pPed); + if (ScriptParams[1]) { + pPed->bKindaStayInSamePlace = true; + pPed->bStopAndShoot = true; + } + else { + pPed->bKindaStayInSamePlace = false; + pPed->bStopAndShoot = false; + } + pPed->m_nLastPedState = PED_NONE; + } case COMMAND_FREEZE_CAR_POSITION_AND_DONT_LOAD_COLLISION: - case COMMAND_FREEZE_CHAR_POSITION_AND_DONT_LOAD_COLLISION: - case COMMAND_FREEZE_OBJECT_POSITION_AND_DONT_LOAD_COLLISION: - case COMMAND_SET_FADE_AND_JUMPCUT_AFTER_RC_EXPLOSION: + { + CollectParameters(&m_nIp, 2); + CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]); + assert(pVehicle); + if (ScriptParams[1]) { + pVehicle->bIsFrozen = true; + pVehicle->bInfiniteMass = true; + if (m_bIsMissionScript) { + CWorld::Remove(pVehicle); + pVehicle->bIsStaticWaitingForCollision = true; + CWorld::Add(pVehicle); + } + } + else { + pVehicle->bIsFrozen = false; + pVehicle->bInfiniteMass = false; + } + return 0; + } + //case COMMAND_FREEZE_CHAR_POSITION_AND_DONT_LOAD_COLLISION: + //case COMMAND_FREEZE_OBJECT_POSITION_AND_DONT_LOAD_COLLISION: + //case COMMAND_SET_FADE_AND_JUMPCUT_AFTER_RC_EXPLOSION: default: assert(0); } @@ -10131,51 +11715,391 @@ int8 CRunningScript::ProcessCommands1400To1499(int32 command) { switch (command) { case COMMAND_REGISTER_VIGILANTE_LEVEL: + CollectParameters(&m_nIp, 1); + debug("REGISTER_VIGILANTE_LEVEL not implemented\n"); // TODO(MIAMI) case COMMAND_CLEAR_ALL_CHAR_ANIMS: - assert(0); + { + CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]); + assert(pPed); + if (!pPed->bInVehicle) { + pPed->m_pVehicleAnim = nil; + pPed->RestartNonPartialAnims(); + RpAnimBlendClumpRemoveAllAssociations(pPed->GetClump()); + pPed->SetPedState(PED_IDLE); + pPed->SetMoveState(PEDMOVE_STILL); + pPed->m_nLastPedState = PED_NONE; + pPed->ClearAimFlag(); + pPed->ClearLookFlag(); + pPed->bIsPointingGunAt = false; + if (pPed->IsPlayer()) + ((CPlayerPed*)pPed)->m_fMoveSpeed = 0.0f; + else + pPed->m_nStoredMoveState = PEDMOVE_STILL; + CAnimManager::AddAnimation(pPed->GetClump(), pPed->m_animGroup, ANIM_IDLE_STANCE); + pPed->bIsPedDieAnimPlaying = false; + } + return 0; + } case COMMAND_SET_MAXIMUM_NUMBER_OF_CARS_IN_GARAGE: CollectParameters(&m_nIp, 2); CGarages::SetMaxNumStoredCarsForGarage(ScriptParams[0], ScriptParams[1]); break; case COMMAND_WANTED_STARS_ARE_FLASHING: + { + static bool bShowed = false; + if (!bShowed) { + debug("WANTED_STARS_ARE_FLASHING not implemented, default to FALSE\n"); + bShowed = true; + } + UpdateCompareFlag(false); + return 0; + } case COMMAND_SET_ALLOW_HURRICANES: + CollectParameters(&m_nIp, 1); + CStats::NoMoreHurricanes = ScriptParams[0]; + return 0; case COMMAND_PLAY_ANNOUNCEMENT: + { + CollectParameters(&m_nIp, 1); + debug("PLAY_ANNOUNCEMENT not implemented, skipping\n"); + return 0; + } case COMMAND_SET_PLAYER_IS_IN_STADIUM: + { + CollectParameters(&m_nIp, 1); + CTheScripts::bPlayerIsInTheStatium = ScriptParams[0]; + return 0; + } case COMMAND_GET_BUS_FARES_COLLECTED_BY_PLAYER: + { + CollectParameters(&m_nIp, 1); + debug("GET_BUS_FARES_COLLECTED_BY_PLAYER not implemented\n"); // TODO(MIAMI) + ScriptParams[0] = 0; + StoreParameters(&m_nIp, 1); + } case COMMAND_SET_CHAR_OBJ_BUY_ICE_CREAM: + { + CollectParameters(&m_nIp, 2); + CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]); + assert(pPed); + CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[1]); + assert(pVehicle); + ScriptParams[0] = 0; + if (pPed->m_objective == OBJECTIVE_NONE && !pPed->bHasAlreadyUsedAttractor) { + C2dEffect* pEffect = (C2dEffect*)GetPedAttractorManager()->GetEffectForIceCreamVan(pVehicle, pPed->GetPosition()); // has to be casted, because inner methods are const + if ((pPed->GetPosition() - pEffect->pos).MagnitudeSqr() < SQR(20.0f)) { + if (GetPedAttractorManager()->HasEmptySlot(pEffect) && GetPedAttractorManager()->IsApproachable(pEffect, pVehicle->GetMatrix(), 0, pPed)) { + if (GetPedAttractorManager()->RegisterPedWithAttractor(pPed, pEffect, pVehicle->GetMatrix())) + ScriptParams[0] = 1; + } + } + } + StoreParameters(&m_nIp, 1); + return 0; + } case COMMAND_DISPLAY_RADAR: + CollectParameters(&m_nIp, 1); + debug("DISPLAY_RADAR not implemented\n"); + return 0; case COMMAND_REGISTER_BEST_POSITION: + CollectParameters(&m_nIp, 2); + debug("REGISTER_BEST_POSITION not implemented\n"); + return 0; case COMMAND_IS_PLAYER_IN_INFO_ZONE: + { + CollectParameters(&m_nIp, 1); + char key[KEY_LENGTH_IN_SCRIPT]; + CTheScripts::ReadTextLabelFromScript(&m_nIp, key); + m_nIp += KEY_LENGTH_IN_SCRIPT; + static bool bShowed = false; + if (!bShowed) { + debug("IS_PLAYER_IN_INFO_ZONE not implemented, default to FALSE\n"); + bShowed = true; + } + UpdateCompareFlag(false); + return 0; + } case COMMAND_CLEAR_CHAR_ICE_CREAM_PURCHASE: + { + CollectParameters(&m_nIp, 1); + CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]); + assert(pPed); + if (pPed->m_attractor) + GetPedAttractorManager()->DeRegisterPed(pPed, pPed->m_attractor); + return 0; + } case COMMAND_IS_IN_CAR_FIRE_BUTTON_PRESSED: + UpdateCompareFlag(CPad::GetPad(0)->GetCarGunFired()); + return 0; case COMMAND_HAS_CHAR_ATTEMPTED_ATTRACTOR: + { + CollectParameters(&m_nIp, 1); + CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]); + assert(pPed); + UpdateCompareFlag(pPed->bHasAlreadyUsedAttractor); + return 0; + } case COMMAND_SET_LOAD_COLLISION_FOR_CAR_FLAG: + { + CollectParameters(&m_nIp, 2); + CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]); + assert(pVehicle); + if (ScriptParams[1]) { + pVehicle->bDontLoadCollision = false; + if (m_bMissionFlag) { + CWorld::Remove(pVehicle); + pVehicle->bIsStaticWaitingForCollision = true; + CWorld::Add(pVehicle); + } + } + else { + pVehicle->bDontLoadCollision = true; + if (pVehicle->bIsStaticWaitingForCollision) { + pVehicle->bIsStaticWaitingForCollision = false; + if (!pVehicle->IsStatic()) + pVehicle->AddToMovingList(); + } + } + return 0; + } case COMMAND_SET_LOAD_COLLISION_FOR_CHAR_FLAG: - case COMMAND_SET_LOAD_COLLISION_FOR_OBJECT_FLAG: + { + CollectParameters(&m_nIp, 2); + CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]); + assert(pPed); + if (ScriptParams[1]) { + pPed->bDontLoadCollision = false; + if (m_bMissionFlag) { + CWorld::Remove(pPed); + pPed->bIsStaticWaitingForCollision = true; + CWorld::Add(pPed); + } + } + else { + pPed->bDontLoadCollision = true; + if (pPed->bIsStaticWaitingForCollision) { + pPed->bIsStaticWaitingForCollision = false; + if (!pPed->IsStatic()) + pPed->AddToMovingList(); + } + } + return 0; + } + //case COMMAND_SET_LOAD_COLLISION_FOR_OBJECT_FLAG: case COMMAND_ADD_BIG_GUN_FLASH: + { + CollectParameters(&m_nIp, 6); + debug("ADD_BIG_GUN_FLASH not implemented\n"); // TODO(MIAMI) + return 0; + } case COMMAND_HAS_CHAR_BOUGHT_ICE_CREAM: + { + CollectParameters(&m_nIp, 1); + CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]); + assert(pPed); + UpdateCompareFlag(pPed->bBoughtIceCream); + return 0; + } case COMMAND_GET_PROGRESS_PERCENTAGE: + *(float*)&ScriptParams[0] = CStats::GetPercentageProgress(); + StoreParameters(&m_nIp, 1); + return 0; case COMMAND_SET_SHORTCUT_PICKUP_POINT: + { + CollectParameters(&m_nIp, 4); + debug("SET_SHORTCUT_PICKUP_POINT not implemented, skipping\n"); + return 0; + } case COMMAND_SET_SHORTCUT_DROPOFF_POINT_FOR_MISSION: + { + CollectParameters(&m_nIp, 4); + debug("SET_SHORTCUT_DROPOFF_POINT_FOR_MISSION not implemented, skipping"); + return 0; + } case COMMAND_GET_RANDOM_ICE_CREAM_CUSTOMER_IN_AREA: - case COMMAND_GET_RANDOM_ICE_CREAM_CUSTOMER_IN_ZONE: + CollectParameters(&m_nIp, 7); + debug("GET_RANDOM_ICE_CREAM_CUSTOMER_IN_AREA not implemented\n"); // TODO(MIAMI) + ScriptParams[0] = -1; + StoreParameters(&m_nIp, 1); + return 0; + //case COMMAND_GET_RANDOM_ICE_CREAM_CUSTOMER_IN_ZONE: case COMMAND_UNLOCK_ALL_CAR_DOORS_IN_AREA: + CollectParameters(&m_nIp, 4); + debug("UNLOCK_ALL_CAR_DOORS_IN_AREA not implemented\n"); // TODO(MIAMI) + return 0; case COMMAND_SET_GANG_ATTACK_PLAYER_WITH_COPS: + CollectParameters(&m_nIp, 2); + CGangs::SetWillAttackPlayerWithCops((ePedType)((int)PEDTYPE_GANG1 + ScriptParams[0]), !!ScriptParams[1]); + return 0; case COMMAND_SET_CHAR_FRIGHTENED_IN_JACKED_CAR: + assert(0); case COMMAND_SET_VEHICLE_TO_FADE_IN: + { + CollectParameters(&m_nIp, 2); + CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]); + assert(pVehicle); + CVisibilityPlugins::SetClumpAlpha(pVehicle->GetClump(), ScriptParams[1]); + return 0; + } case COMMAND_REGISTER_ODDJOB_MISSION_PASSED: + ++CStats::MissionsPassed; + CStats::CheckPointReachedSuccessfully(); + CTheScripts::LastMissionPassedTime = CTimer::GetTimeInMilliseconds(); + // CGameLogic::RemoveShortCutDropOffPointForMission(); // TODO(MIAMI) case COMMAND_IS_PLAYER_IN_SHORTCUT_TAXI: + { + CollectParameters(&m_nIp, 1); + static bool bShowed = false; + if (!bShowed) { + debug("IS_PLAYER_IN_SHORTCUT_TAXI not implemented, default to FALSE\n"); + bShowed = true; + } + UpdateCompareFlag(false); + return 0; + } case COMMAND_IS_CHAR_DUCKING: + { + CollectParameters(&m_nIp, 1); + CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]); + assert(pPed); + UpdateCompareFlag(RpAnimBlendClumpGetAssociation(pPed->GetClump(), ANIM_DUCK_DOWN) != nil); + return 0; + } case COMMAND_CREATE_DUST_EFFECT_FOR_CUTSCENE_HELI: + { + CollectParameters(&m_nIp, 3); + debug("CREATE_DUST_EFFECT_FOR_CUTSCENE_HELI not implemented\n"); // TODO(MIAMI) + return 0; + } case COMMAND_REGISTER_FIRE_LEVEL: + CollectParameters(&m_nIp, 1); + debug("REGISTER_FIRE_LEVEL not implemented\n"); // TODO(MIAMI) + return 0; case COMMAND_IS_AUSTRALIAN_GAME: + UpdateCompareFlag(false); // should we make some check? case COMMAND_DISARM_CAR_BOMB: + { + CollectParameters(&m_nIp, 1); + CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]); + if (pVehicle->m_bombType != CARBOMB_NONE) { + pVehicle->m_bombType = CARBOMB_NONE; + pVehicle->m_pBombRigger = nil; + } + return 0; + } default: assert(0); } return -1; } +bool CRunningScript::CheckDamagedWeaponType(int32 actual, int32 type) +{ + if (actual == -1) + return false; + + if (type == WEAPONTYPE_ANYMELEE) { + if (actual <= WEAPONTYPE_CHAINSAW) + return true; + if (actual - WEAPONTYPE_GRENADE <= WEAPONTYPE_MINIGUN) + return false; + return false; + } + + if (type != WEAPONTYPE_ANYWEAPON) + return false; + + switch (actual) { + case WEAPONTYPE_UNARMED: + case WEAPONTYPE_BRASSKNUCKLE: + case WEAPONTYPE_SCREWDRIVER: + case WEAPONTYPE_GOLFCLUB: + case WEAPONTYPE_NIGHTSTICK: + case WEAPONTYPE_KNIFE: + case WEAPONTYPE_BASEBALLBAT: + case WEAPONTYPE_HAMMER: + case WEAPONTYPE_CLEAVER: + case WEAPONTYPE_MACHETE: + case WEAPONTYPE_KATANA: + case WEAPONTYPE_CHAINSAW: + case WEAPONTYPE_GRENADE: + case WEAPONTYPE_DETONATOR_GRENADE: + case WEAPONTYPE_TEARGAS: + case WEAPONTYPE_MOLOTOV: + case WEAPONTYPE_ROCKET: + case WEAPONTYPE_COLT45: + case WEAPONTYPE_PYTHON: + case WEAPONTYPE_SHOTGUN: + case WEAPONTYPE_SPAS12_SHOTGUN: + case WEAPONTYPE_STUBBY_SHOTGUN: + case WEAPONTYPE_TEC9: + case WEAPONTYPE_UZI: + case WEAPONTYPE_SILENCED_INGRAM: + case WEAPONTYPE_MP5: + case WEAPONTYPE_M4: + case WEAPONTYPE_RUGER: + case WEAPONTYPE_SNIPERRIFLE: + case WEAPONTYPE_LASERSCOPE: + case WEAPONTYPE_ROCKETLAUNCHER: + case WEAPONTYPE_FLAMETHROWER: + case WEAPONTYPE_M60: + case WEAPONTYPE_MINIGUN: + case WEAPONTYPE_DETONATOR: + case WEAPONTYPE_HELICANNON: + case WEAPONTYPE_CAMERA: + case WEAPONTYPE_EXPLOSION: + case WEAPONTYPE_UZI_DRIVEBY: + return true; + case WEAPONTYPE_HEALTH: + case WEAPONTYPE_ARMOUR: + case WEAPONTYPE_RAMMEDBYCAR: + case WEAPONTYPE_RUNOVERBYCAR: + case WEAPONTYPE_DROWNING: + case WEAPONTYPE_FALL: + case WEAPONTYPE_UNIDENTIFIED: + return false; + } + + return false; +} + +bool CRunningScript::ThisIsAValidRandomCop(int32 mi, bool cop, bool swat, bool fbi, bool army, bool miami) +{ + switch (mi) + { + case MI_COP: if (cop) return true; + case MI_SWAT: if (swat) return true; + case MI_FBI: if (fbi) return true; + case MI_ARMY: if (army) return true; + default: + return miami && (mi >= MI_VICE1 && mi <= MI_VICE8); + } +} + +void CTheScripts::RemoveThisPed(CPed* pPed) +{ + if (pPed) { + bool bWasMissionPed = pPed->CharCreatedBy == MISSION_CHAR; + if (pPed->InVehicle() && pPed->m_pMyVehicle) { + if (pPed->m_pMyVehicle->pDriver == pPed) { + pPed->m_pMyVehicle->RemoveDriver(); + pPed->m_pMyVehicle->SetStatus(STATUS_ABANDONED); + if (pPed->m_pMyVehicle->m_nDoorLock == CARLOCK_LOCKED_INITIALLY) + pPed->m_pMyVehicle->m_nDoorLock = CARLOCK_UNLOCKED; + if (pPed->m_nPedType == PEDTYPE_COP && pPed->m_pMyVehicle->IsLawEnforcementVehicle()) + pPed->m_pMyVehicle->ChangeLawEnforcerState(0); + } + else { + pPed->m_pMyVehicle->RemovePassenger(pPed); + } + } + CWorld::RemoveReferencesToDeletedObject(pPed); + delete pPed; + if (bWasMissionPed) + --CPopulation::ms_nTotalMissionPeds; + } +} + int32 CTheScripts::GetNewUniqueScriptSphereIndex(int32 index) { if (ScriptSphereArray[index].m_Index >= UINT16_MAX - 1) @@ -11030,6 +12954,64 @@ void CRunningScript::LocateCarCommand(int32 command, uint32* pIp) } } +void CRunningScript::LocateObjectCommand(int32 command, uint32* pIp) +{ + bool b3D, result, debug; + float X, Y, Z, dX, dY, dZ; + switch (command) { + case COMMAND_LOCATE_OBJECT_3D: + b3D = true; + break; + default: + b3D = false; + break; + } + CollectParameters(pIp, b3D ? 8 : 6); + CObject* pObject = CPools::GetObjectPool()->GetAt(ScriptParams[0]); + assert(pObject); + CVector pos = pObject->GetPosition(); + X = *(float*)&ScriptParams[1]; + Y = *(float*)&ScriptParams[2]; + if (b3D) { + Z = *(float*)&ScriptParams[3]; + dX = *(float*)&ScriptParams[4]; + dY = *(float*)&ScriptParams[5]; + dZ = *(float*)&ScriptParams[6]; + debug = ScriptParams[7]; + } + else { + dX = *(float*)&ScriptParams[3]; + dY = *(float*)&ScriptParams[4]; + debug = ScriptParams[5]; + } + result = false; + bool in_area; + if (b3D) { + in_area = X - dX <= pos.x && + X + dX >= pos.x && + Y - dY <= pos.y && + Y + dY >= pos.y && + Z - dZ <= pos.z && + Z + dZ >= pos.z; + } + else { + in_area = X - dX <= pos.x && + X + dX >= pos.x && + Y - dY <= pos.y && + Y + dY >= pos.y; + } + result = in_area; + UpdateCompareFlag(result); + if (debug) + CTheScripts::HighlightImportantArea((uintptr)this + m_nIp, X - dX, Y - dY, X + dX, Y + dY, b3D ? Z : MAP_Z_LOW_LIMIT); + if (CTheScripts::DbgFlag) { + if (b3D) + CTheScripts::DrawDebugCube(X - dX, Y - dY, Z - dZ, X + dX, Y + dY, Z + dZ); + else + CTheScripts::DrawDebugSquare(X - dX, Y - dY, X + dX, Y + dY); + } +} + void CRunningScript::LocateSniperBulletCommand(int32 command, uint32* pIp) { bool b3D, result, debug; @@ -11527,6 +13509,88 @@ void CRunningScript::CarInAreaCheckCommand(int32 command, uint32* pIp) } } +void CRunningScript::ObjectInAreaCheckCommand(int32 command, uint32* pIp) +{ + bool b3D, result, debug; + float infX, infY, infZ, supX, supY, supZ; + switch (command) { + case COMMAND_IS_OBJECT_IN_AREA_3D: + b3D = true; + break; + default: + b3D = false; + break; + } + CollectParameters(pIp, b3D ? 8 : 6); + CObject* pObject = CPools::GetObjectPool()->GetAt(ScriptParams[0]); + assert(pObject); + CVector pos = pObject->GetPosition(); + infX = *(float*)&ScriptParams[1]; + infY = *(float*)&ScriptParams[2]; + if (b3D) { + infZ = *(float*)&ScriptParams[3]; + supX = *(float*)&ScriptParams[4]; + supY = *(float*)&ScriptParams[5]; + supZ = *(float*)&ScriptParams[6]; + if (infZ > supZ) { + infZ = *(float*)&ScriptParams[6]; + supZ = *(float*)&ScriptParams[3]; + } + debug = ScriptParams[7]; + } + else { + supX = *(float*)&ScriptParams[3]; + supY = *(float*)&ScriptParams[4]; + debug = ScriptParams[5]; + } + if (infX > supX) { + float tmp = infX; + infX = supX; + supX = tmp; + } + if (infY > supY) { + float tmp = infY; + infY = supY; + supY = tmp; + } + result = false; + bool in_area; + if (b3D) { + in_area = infX <= pos.x && + supX >= pos.x && + infY <= pos.y && + supY >= pos.y && + infZ <= pos.z && + supZ >= pos.z; + } + else { + in_area = infX <= pos.x && + supX >= pos.x && + infY <= pos.y && + supY >= pos.y; + } + if (in_area) { + switch (command) { + case COMMAND_IS_OBJECT_IN_AREA_2D: + case COMMAND_IS_OBJECT_IN_AREA_3D: + result = true; + break; + default: + assert(false); + break; + } + } + UpdateCompareFlag(result); + if (debug) + CTheScripts::HighlightImportantArea((uintptr)this + m_nIp, infX, infY, supX, supY, b3D ? (infZ + supZ) / 2 : MAP_Z_LOW_LIMIT); + if (CTheScripts::DbgFlag) { + if (b3D) + CTheScripts::DrawDebugCube(infX, infY, infZ, supX, supY, supZ); + else + CTheScripts::DrawDebugSquare(infX, infY, supX, supY); + } +} + void CRunningScript::DoDeatharrestCheck() { if (!m_bDeatharrestEnabled) @@ -11540,29 +13604,6 @@ void CRunningScript::DoDeatharrestCheck() while (m_nStackPointer > 1) --m_nStackPointer; m_nIp = m_anStack[--m_nStackPointer]; - int16 messageId; - if (pPlayer->IsRestartingAfterDeath()) - messageId = 0; - else if (pPlayer->IsRestartingAfterArrest()) - messageId = 5; - else - messageId = 10; - messageId += CGeneral::GetRandomNumberInRange(0, 5); - bool found = false; - for (int16 contact = 0; !found && contact < MAX_NUM_CONTACTS; contact++) { - int contactFlagOffset = CTheScripts::OnAMissionForContactFlag[contact]; - if (contactFlagOffset && CTheScripts::ScriptSpace[contactFlagOffset] == 1) { - messageId += CTheScripts::BaseBriefIdForContact[contact]; - found = true; - } - } - if (!found) - messageId = 8001; - char tmp[16]; - sprintf(tmp, "%d", messageId); - CMessages::ClearSmallMessagesOnly(); - wchar* text = TheText.Get(tmp); - // ...and do nothing about it *(int32*)&CTheScripts::ScriptSpace[CTheScripts::OnAMissionFlag] = 0; m_bDeatharrestExecuted = true; m_nWakeTime = 0; @@ -11706,8 +13747,8 @@ void CTheScripts::RenderTheScriptDebugLines() RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)0); } -#define SCRIPT_DATA_SIZE sizeof(CTheScripts::OnAMissionFlag) + sizeof(CTheScripts::BaseBriefIdForContact) + sizeof(CTheScripts::OnAMissionForContactFlag) +\ - sizeof(CTheScripts::CollectiveArray) + 4 * sizeof(uint32) * MAX_NUM_BUILDING_SWAPS + 2 * sizeof(uint32) * MAX_NUM_INVISIBILITY_SETTINGS + 5 * sizeof(uint32) +#define SCRIPT_DATA_SIZE sizeof(CTheScripts::OnAMissionFlag) +\ + 4 * sizeof(uint32) * MAX_NUM_BUILDING_SWAPS + 2 * sizeof(uint32) * MAX_NUM_INVISIBILITY_SETTINGS + 5 * sizeof(uint32) void CTheScripts::SaveAllScripts(uint8* buf, uint32* size) { @@ -11727,12 +13768,6 @@ INITSAVEBUF uint32 script_data_size = SCRIPT_DATA_SIZE; WriteSaveBuf(buf, script_data_size); WriteSaveBuf(buf, OnAMissionFlag); - for (uint32 i = 0; i < MAX_NUM_CONTACTS; i++) { - WriteSaveBuf(buf, OnAMissionForContactFlag[i]); - WriteSaveBuf(buf, BaseBriefIdForContact[i]); - } - for (uint32 i = 0; i < MAX_NUM_COLLECTIVES; i++) - WriteSaveBuf(buf, CollectiveArray[i]); WriteSaveBuf(buf, NextFreeCollectiveIndex); for (uint32 i = 0; i < MAX_NUM_BUILDING_SWAPS; i++) { CBuilding* pBuilding = BuildingSwapArray[i].m_pBuilding; @@ -11805,12 +13840,6 @@ INITSAVEBUF ScriptSpace[i] = ReadSaveBuf(buf); assert(ReadSaveBuf(buf) == SCRIPT_DATA_SIZE); OnAMissionFlag = ReadSaveBuf(buf); - for (uint32 i = 0; i < MAX_NUM_CONTACTS; i++) { - OnAMissionForContactFlag[i] = ReadSaveBuf(buf); - BaseBriefIdForContact[i] = ReadSaveBuf(buf); - } - for (uint32 i = 0; i < MAX_NUM_COLLECTIVES; i++) - CollectiveArray[i] = ReadSaveBuf(buf); NextFreeCollectiveIndex = ReadSaveBuf(buf); for (uint32 i = 0; i < MAX_NUM_BUILDING_SWAPS; i++) { uint32 type = ReadSaveBuf(buf); diff --git a/src/control/Script.h b/src/control/Script.h index 9931f13e..57b997b1 100644 --- a/src/control/Script.h +++ b/src/control/Script.h @@ -15,6 +15,12 @@ class CPlayerInfo; class CRunningScript; #define KEY_LENGTH_IN_SCRIPT 8 +#define SPHERE_MARKER_R 252 +#define SPHERE_MARKER_G 138 +#define SPHERE_MARKER_B 242 +#define SPHERE_MARKER_A 228 +#define SPHERE_MARKER_PULSE_PERIOD 2048 +#define SPHERE_MARKER_PULSE_FRACTION 0.1f struct intro_script_rectangle { @@ -221,20 +227,18 @@ enum { }; enum { - SIZE_MAIN_SCRIPT = 128 * 1024, - SIZE_MISSION_SCRIPT = 32 * 1024, + SIZE_MAIN_SCRIPT = 225512, + SIZE_MISSION_SCRIPT = 35000, SIZE_SCRIPT_SPACE = SIZE_MAIN_SCRIPT + SIZE_MISSION_SCRIPT }; enum { MAX_NUM_SCRIPTS = 128, - MAX_NUM_CONTACTS = 16, MAX_NUM_INTRO_TEXT_LINES = 2, MAX_NUM_INTRO_RECTANGLES = 16, MAX_NUM_SCRIPT_SRPITES = 16, MAX_NUM_SCRIPT_SPHERES = 16, - MAX_NUM_COLLECTIVES = 32, - MAX_NUM_USED_OBJECTS = 200, + MAX_NUM_USED_OBJECTS = 220, MAX_NUM_MISSION_SCRIPTS = 120, MAX_NUM_BUILDING_SWAPS = 25, MAX_NUM_INVISIBILITY_SETTINGS = 20, @@ -245,13 +249,10 @@ class CTheScripts { static uint8 ScriptSpace[SIZE_SCRIPT_SPACE]; static CRunningScript ScriptsArray[MAX_NUM_SCRIPTS]; - static int32 BaseBriefIdForContact[MAX_NUM_CONTACTS]; - static int32 OnAMissionForContactFlag[MAX_NUM_CONTACTS]; static intro_text_line IntroTextLines[MAX_NUM_INTRO_TEXT_LINES]; static intro_script_rectangle IntroRectangles[MAX_NUM_INTRO_RECTANGLES]; static CSprite2d ScriptSprites[MAX_NUM_SCRIPT_SRPITES]; static script_sphere_struct ScriptSphereArray[MAX_NUM_SCRIPT_SPHERES]; - static tCollectiveData CollectiveArray[MAX_NUM_COLLECTIVES]; static tUsedObject UsedObjectArray[MAX_NUM_USED_OBJECTS]; static int32 MultiScriptArray[MAX_NUM_MISSION_SCRIPTS]; static tBuildingSwap BuildingSwapArray[MAX_NUM_BUILDING_SWAPS]; @@ -275,14 +276,17 @@ class CTheScripts static uint32 LargestMissionScriptSize; static uint32 MainScriptSize; static uint8 FailCurrentMission; - static uint8 CountdownToMakePlayerUnsafe; - static uint8 DelayMakingPlayerUnsafeThisTime; static uint16 NumScriptDebugLines; static uint16 NumberOfIntroRectanglesThisFrame; static uint16 NumberOfIntroTextLinesThisFrame; static uint8 UseTextCommands; static uint16 CommandsExecuted; static uint16 ScriptsUpdated; + static uint8 RiotIntensity; + static uint32 LastMissionPassedTime; + static uint16 NumberOfExclusiveMissionScripts; + static bool bPlayerIsInTheStatium; + static bool bPlayerHasMetDebbieHarry; public: static void Init(); @@ -306,9 +310,6 @@ public: static int32* GetPointerToScriptVariable(int32 offset) { assert(offset >= 8 && offset < CTheScripts::GetSizeOfVariableSpace()); return (int32*)&ScriptSpace[offset]; } - static void ResetCountdownToMakePlayerUnsafe() { CountdownToMakePlayerUnsafe = 0; } - static bool IsCountdownToMakePlayerUnsafeOn() { return CountdownToMakePlayerUnsafe != 0; } - static int32 Read4BytesFromScript(uint32* pIp) { int32 retval = ScriptSpace[*pIp + 3] << 24 | ScriptSpace[*pIp + 2] << 16 | ScriptSpace[*pIp + 1] << 8 | ScriptSpace[*pIp]; *pIp += 4; @@ -371,6 +372,8 @@ private: static int32 AddScriptSphere(int32 id, CVector pos, float radius); static int32 GetNewUniqueScriptSphereIndex(int32 index); static void RemoveScriptSphere(int32 index); + static void RemoveScriptTextureDictionary(); + static void RemoveThisPed(CPed* pPed); friend class CRunningScript; friend class CHud; @@ -414,6 +417,7 @@ class CRunningScript uint32 m_anStack[MAX_STACK_DEPTH]; uint16 m_nStackPointer; int32 m_anLocalVariables[NUM_LOCAL_VARS + NUM_TIMERS]; + bool m_bIsActive; bool m_bCondResult; bool m_bIsMissionScript; bool m_bSkipWakeTime; @@ -484,13 +488,16 @@ private: void PlayerInAngledAreaCheckCommand(int32, uint32*); void CharInAreaCheckCommand(int32, uint32*); void CarInAreaCheckCommand(int32, uint32*); + void LocateObjectCommand(int32, uint32*); + void ObjectInAreaCheckCommand(int32, uint32*); float LimitAngleOnCircle(float angle) { return angle < 0.0f ? angle + 360.0f : angle; } - bool ThisIsAValidRandomPed(uint32 pedtype) { + bool ThisIsAValidRandomPed(uint32 pedtype, int civ, int gang, int criminal) { switch (pedtype) { case PEDTYPE_CIVMALE: case PEDTYPE_CIVFEMALE: + return civ; case PEDTYPE_GANG1: case PEDTYPE_GANG2: case PEDTYPE_GANG3: @@ -500,11 +507,16 @@ private: case PEDTYPE_GANG7: case PEDTYPE_GANG8: case PEDTYPE_GANG9: + return gang; case PEDTYPE_CRIMINAL: case PEDTYPE_PROSTITUTE: - return true; + return criminal; default: return false; } } + + bool CheckDamagedWeaponType(int32 actual, int32 type); + + static bool ThisIsAValidRandomCop(int32 mi, bool cop, bool swat, bool fbi, bool army, bool miami); }; diff --git a/src/control/SetPieces.cpp b/src/control/SetPieces.cpp new file mode 100644 index 00000000..9b4e0075 --- /dev/null +++ b/src/control/SetPieces.cpp @@ -0,0 +1,319 @@ +#include "common.h" + +#include "SetPieces.h" +#include "Automobile.h" +#include "CarAI.h" +#include "CopPed.h" +#include "GenericGameStorage.h" +#include "PlayerPed.h" +#include "Timer.h" +#include "Vehicle.h" +#include "Wanted.h" +#include "World.h" + +#define TIME_BETWEEN_SETPIECE_SPAWNS 20000 + +//--MIAMI: file done + +bool CSetPieces::bDebug; +uint32 CSetPieces::NumSetPieces; +CSetPiece CSetPieces::aSetPieces[NUM_SETPIECES]; + +void CSetPieces::Init(void) +{ + bDebug = false; + NumSetPieces = 0; +} + +void CSetPieces::AddOne(uint8 type, CVector2D vTriggerInf, CVector2D vTriggerSup, CVector2D vSpawn1, CVector2D vTarget1, CVector2D vSpawn2, CVector2D vTarget2) +{ + if (NumSetPieces >= NUM_SETPIECES) + return; + aSetPieces[NumSetPieces].m_nType = (eSetPieceType)type; + aSetPieces[NumSetPieces].m_vTriggerInf.x = Min(vTriggerInf.x, vTriggerSup.x); + aSetPieces[NumSetPieces].m_vTriggerInf.y = Min(vTriggerInf.y, vTriggerSup.y); + aSetPieces[NumSetPieces].m_vTriggerSup.x = Max(vTriggerInf.x, vTriggerSup.x); + aSetPieces[NumSetPieces].m_vTriggerSup.y = Max(vTriggerInf.y, vTriggerSup.y); + aSetPieces[NumSetPieces].m_vSpawn1 = vSpawn1; + aSetPieces[NumSetPieces].m_vSpawn2 = vSpawn2; + aSetPieces[NumSetPieces].m_vTarget1 = vTarget1; + aSetPieces[NumSetPieces].m_vTarget2 = vTarget2; + ++NumSetPieces; +} + +void CSetPieces::Update(void) +{ + int nFirst = NumSetPieces * (CTimer::GetFrameCounter() % 8) / 8; + int nLast = NumSetPieces * (CTimer::GetFrameCounter() % 8 + 1) / 8; + for (int i = nFirst; i < nLast; i++) + aSetPieces[i].Update(); +} + +void CSetPieces::Save(uint8* buf, uint32* size) +{ +INITSAVEBUF + WriteSaveBuf(buf, NumSetPieces); + for (int i = 0; i < NUM_SETPIECES; i++) + WriteSaveBuf(buf, aSetPieces[i]); + *size = sizeof(NumSetPieces) + NUM_SETPIECES * sizeof(CSetPiece); +VALIDATESAVEBUF(*size) +} + +void CSetPieces::Load(uint8* buf, uint32 size) +{ +INITSAVEBUF + NumSetPieces = ReadSaveBuf(buf); + for (int i = 0; i < NUM_SETPIECES; i++) + aSetPieces[i] = ReadSaveBuf(buf); +VALIDATESAVEBUF(size) +} + +void CSetPiece::Update(void) +{ + if (m_nLastTimeCreated != 0 && CTimer::GetTimeInMilliseconds() <= m_nLastTimeCreated + TIME_BETWEEN_SETPIECE_SPAWNS) + return; + CVector pos = FindPlayerCoors(); + if (pos.x < m_vTriggerInf.x || pos.x > m_vTriggerSup.x || + pos.y < m_vTriggerInf.y || pos.y > m_vTriggerSup.y) + return; + switch (m_nType) { + case SETPIECE_TWOCOPCARSINALLEY: + { + if (FindPlayerPed()->m_pWanted->m_nWantedLevel < 1 || FindPlayerVehicle()) + return; + CVehicle* pVehicle1 = TryToGenerateCopCar(m_vSpawn1, m_vTarget1); + if (!pVehicle1) + return; + CVehicle* pVehicle2 = TryToGenerateCopCar(m_vSpawn2, m_vTarget2); + if (!pVehicle2) { + CWorld::Remove(pVehicle1); + delete pVehicle1; + return; + } + pVehicle1->SetStatus(STATUS_PHYSICS); + pVehicle1->AutoPilot.m_fMaxTrafficSpeed = pVehicle1->AutoPilot.m_nCruiseSpeed = 4; + pVehicle1->AutoPilot.m_nDrivingStyle = DRIVINGSTYLE_SLOW_DOWN_FOR_CARS; + pVehicle1->AutoPilot.m_nCarMission = MISSION_SLOWLY_DRIVE_TOWARDS_PLAYER_1; + pVehicle1->AutoPilot.m_vecDestinationCoors.x = m_vTarget1.x; + pVehicle1->AutoPilot.m_vecDestinationCoors.y = m_vTarget1.y; + pVehicle1->AutoPilot.m_vecDestinationCoors.z = 0.0f; + pVehicle1->m_nSetPieceExtendedRangeTime = CTimer::GetTimeInMilliseconds() + 25000; + CCarAI::AddPoliceCarOccupants(pVehicle1); + pVehicle2->SetStatus(STATUS_PHYSICS); + pVehicle2->AutoPilot.m_fMaxTrafficSpeed = pVehicle2->AutoPilot.m_nCruiseSpeed = 4; + pVehicle2->AutoPilot.m_nDrivingStyle = DRIVINGSTYLE_SLOW_DOWN_FOR_CARS; + pVehicle2->AutoPilot.m_nCarMission = MISSION_SLOWLY_DRIVE_TOWARDS_PLAYER_1; + pVehicle2->AutoPilot.m_vecDestinationCoors.x = m_vTarget2.x; + pVehicle2->AutoPilot.m_vecDestinationCoors.y = m_vTarget2.y; + pVehicle2->AutoPilot.m_vecDestinationCoors.z = 0.0f; + pVehicle2->m_nSetPieceExtendedRangeTime = CTimer::GetTimeInMilliseconds() + 25000; + CCarAI::AddPoliceCarOccupants(pVehicle2); + m_nLastTimeCreated = CTimer::GetTimeInMilliseconds(); + break; + } + case SETPIECE_CARBLOCKINGPLAYERFROMSIDE: + { + if (FindPlayerPed()->m_pWanted->m_nWantedLevel < 2) + return; + if (!FindPlayerVehicle()) + return; + if (DotProduct2D(FindPlayerSpeed(), (CVector2D)FindPlayerCoors() - m_vSpawn1) >= 0.0f) + return; + CVehicle* pVehicle1 = TryToGenerateCopCar(m_vSpawn1, m_vTarget1); + if (!pVehicle1) + return; + pVehicle1->SetStatus(STATUS_PHYSICS); + pVehicle1->AutoPilot.m_fMaxTrafficSpeed = pVehicle1->AutoPilot.m_nCruiseSpeed = 16; + pVehicle1->AutoPilot.m_nDrivingStyle = DRIVINGSTYLE_PLOUGH_THROUGH; + pVehicle1->AutoPilot.m_nCarMission = MISSION_BLOCKPLAYER_FORWARDANDBACK; + pVehicle1->AutoPilot.m_nTempAction = TEMPACT_GOFORWARD; + pVehicle1->AutoPilot.m_nTimeTempAction = CTimer::GetTimeInMilliseconds() + 100; + pVehicle1->m_nSetPieceExtendedRangeTime = CTimer::GetTimeInMilliseconds() + 10000; + pVehicle1->SetMoveSpeed(2.0f * pVehicle1->GetForward() / 3.0f); + CCarAI::AddPoliceCarOccupants(pVehicle1); + m_nLastTimeCreated = CTimer::GetTimeInMilliseconds(); + return; + } + case SETPIECE_CARRAMMINGPLAYERFROMSIDE: + { + if (FindPlayerPed()->m_pWanted->m_nWantedLevel < 2) + return; + if (!FindPlayerVehicle()) + return; + if (DotProduct2D(FindPlayerSpeed(), (CVector2D)FindPlayerCoors() - m_vSpawn1) >= 0.0f) + return; + CVehicle* pVehicle1 = TryToGenerateCopCar(m_vSpawn1, m_vTarget1); + if (!pVehicle1) + return; + pVehicle1->SetStatus(STATUS_PHYSICS); + pVehicle1->AutoPilot.m_fMaxTrafficSpeed = pVehicle1->AutoPilot.m_nCruiseSpeed = 16; + pVehicle1->AutoPilot.m_nDrivingStyle = DRIVINGSTYLE_AVOID_CARS; + pVehicle1->AutoPilot.m_nCarMission = MISSION_RAMCAR_CLOSE; + pVehicle1->AutoPilot.m_nTempAction = TEMPACT_GOFORWARD; + pVehicle1->AutoPilot.m_nTimeTempAction = CTimer::GetTimeInMilliseconds() + 100; + pVehicle1->m_nSetPieceExtendedRangeTime = CTimer::GetTimeInMilliseconds() + 10000; + pVehicle1->SetMoveSpeed(2.0f * pVehicle1->GetForward() / 3.0f); + CCarAI::AddPoliceCarOccupants(pVehicle1); + m_nLastTimeCreated = CTimer::GetTimeInMilliseconds(); + return; + } + case SETPIECE_CREATECOPPERONFOOT: + { + if (FindPlayerPed()->m_pWanted->m_nWantedLevel < 1 || FindPlayerVehicle()) + return; + CCopPed* pCop = TryToGenerateCopPed(m_vSpawn1); + if (!pCop) + return; + float z = CWorld::FindGroundZForCoord(m_vTarget1.x, m_vTarget1.y); + pCop->bScriptObjectiveCompleted = false; + pCop->SetObjective(OBJECTIVE_GOTO_AREA_ON_FOOT, CVector(m_vTarget1.x, m_vTarget1.y, z)); + pCop->m_nExtendedRangeTimer = CTimer::GetTimeInMilliseconds() + 10000; + m_nLastTimeCreated = CTimer::GetTimeInMilliseconds(); + return; + } + case SETPIECE_CREATETWOCOPPERSONFOOT: + { + if (FindPlayerPed()->m_pWanted->m_nWantedLevel < 1 || FindPlayerVehicle()) + return; + CCopPed* pCop = TryToGenerateCopPed(m_vSpawn1); + if (!pCop) + return; + float z = CWorld::FindGroundZForCoord(m_vTarget1.x, m_vTarget1.y); + pCop->bScriptObjectiveCompleted = false; + pCop->SetObjective(OBJECTIVE_GOTO_AREA_ON_FOOT, CVector(m_vTarget1.x, m_vTarget1.y, z)); + pCop->m_nExtendedRangeTimer = CTimer::GetTimeInMilliseconds() + 10000; + CCopPed* pCop2 = TryToGenerateCopPed(m_vSpawn2); + if (!pCop2) { + CWorld::Remove(pCop); + delete pCop; + return; + } + z = CWorld::FindGroundZForCoord(m_vTarget2.x, m_vTarget2.y); + pCop2->bScriptObjectiveCompleted = false; + pCop2->SetObjective(OBJECTIVE_GOTO_AREA_ON_FOOT, CVector(m_vTarget2.x, m_vTarget2.y, z)); + pCop2->m_nExtendedRangeTimer = CTimer::GetTimeInMilliseconds() + 10000; + m_nLastTimeCreated = CTimer::GetTimeInMilliseconds(); + return; + } + case SETPIECE_TWOCARSBLOCKINGPLAYERFROMSIDE: + { + if (FindPlayerPed()->m_pWanted->m_nWantedLevel < 2) + return; + if (!FindPlayerVehicle()) + return; + if (DotProduct2D(FindPlayerSpeed(), (CVector2D)FindPlayerCoors() - m_vSpawn1) >= 0.0f) + return; + CVehicle* pVehicle1 = TryToGenerateCopCar(m_vSpawn1, m_vTarget1); + if (!pVehicle1) + return; + pVehicle1->SetStatus(STATUS_PHYSICS); + pVehicle1->AutoPilot.m_fMaxTrafficSpeed = pVehicle1->AutoPilot.m_nCruiseSpeed = 16; + pVehicle1->AutoPilot.m_nDrivingStyle = DRIVINGSTYLE_PLOUGH_THROUGH; + pVehicle1->AutoPilot.m_nCarMission = MISSION_BLOCKPLAYER_FORWARDANDBACK; + pVehicle1->AutoPilot.m_nTempAction = TEMPACT_GOFORWARD; + pVehicle1->AutoPilot.m_nTimeTempAction = CTimer::GetTimeInMilliseconds() + 100; + pVehicle1->m_nSetPieceExtendedRangeTime = CTimer::GetTimeInMilliseconds() + 10000; + pVehicle1->SetMoveSpeed(2.0f * pVehicle1->GetForward() / 3.0f); + CCarAI::AddPoliceCarOccupants(pVehicle1); + CVehicle* pVehicle2 = TryToGenerateCopCar(m_vSpawn2, m_vTarget2); + if (!pVehicle2) { + CWorld::Remove(pVehicle1); + delete pVehicle1; + return; + } + pVehicle2->SetStatus(STATUS_PHYSICS); + pVehicle2->AutoPilot.m_fMaxTrafficSpeed = pVehicle1->AutoPilot.m_nCruiseSpeed = 16; + pVehicle2->AutoPilot.m_nDrivingStyle = DRIVINGSTYLE_PLOUGH_THROUGH; + pVehicle2->AutoPilot.m_nCarMission = MISSION_BLOCKPLAYER_FORWARDANDBACK; + pVehicle2->AutoPilot.m_nTempAction = TEMPACT_GOFORWARD; + pVehicle2->AutoPilot.m_nTimeTempAction = CTimer::GetTimeInMilliseconds() + 100; + pVehicle2->m_nSetPieceExtendedRangeTime = CTimer::GetTimeInMilliseconds() + 10000; + pVehicle2->SetMoveSpeed(2.0f * pVehicle2->GetForward() / 3.0f); + CCarAI::AddPoliceCarOccupants(pVehicle2); + m_nLastTimeCreated = CTimer::GetTimeInMilliseconds(); + return; + } + case SETPIECE_TWOCARSRAMMINGPLAYERFROMSIDE: + { + if (FindPlayerPed()->m_pWanted->m_nWantedLevel < 2) + return; + if (!FindPlayerVehicle()) + return; + if (DotProduct2D(FindPlayerSpeed(), (CVector2D)FindPlayerCoors() - m_vSpawn1) >= 0.0f) + return; + CVehicle* pVehicle1 = TryToGenerateCopCar(m_vSpawn1, m_vTarget1); + if (!pVehicle1) + return; + pVehicle1->SetStatus(STATUS_PHYSICS); + pVehicle1->AutoPilot.m_fMaxTrafficSpeed = pVehicle1->AutoPilot.m_nCruiseSpeed = 16; + pVehicle1->AutoPilot.m_nDrivingStyle = DRIVINGSTYLE_AVOID_CARS; + pVehicle1->AutoPilot.m_nCarMission = MISSION_RAMCAR_CLOSE; + pVehicle1->AutoPilot.m_nTempAction = TEMPACT_GOFORWARD; + pVehicle1->AutoPilot.m_nTimeTempAction = CTimer::GetTimeInMilliseconds() + 100; + pVehicle1->m_nSetPieceExtendedRangeTime = CTimer::GetTimeInMilliseconds() + 10000; + pVehicle1->SetMoveSpeed(2.0f * pVehicle1->GetForward() / 3.0f); + CCarAI::AddPoliceCarOccupants(pVehicle1); + CVehicle* pVehicle2 = TryToGenerateCopCar(m_vSpawn2, m_vTarget2); + if (!pVehicle2) { + CWorld::Remove(pVehicle2); + delete pVehicle2; + return; + } + pVehicle2->SetStatus(STATUS_PHYSICS); + pVehicle2->AutoPilot.m_fMaxTrafficSpeed = pVehicle2->AutoPilot.m_nCruiseSpeed = 16; + pVehicle2->AutoPilot.m_nDrivingStyle = DRIVINGSTYLE_AVOID_CARS; + pVehicle2->AutoPilot.m_nCarMission = MISSION_RAMCAR_CLOSE; + pVehicle2->AutoPilot.m_nTempAction = TEMPACT_GOFORWARD; + pVehicle2->AutoPilot.m_nTimeTempAction = CTimer::GetTimeInMilliseconds() + 100; + pVehicle2->m_nSetPieceExtendedRangeTime = CTimer::GetTimeInMilliseconds() + 10000; + pVehicle2->SetMoveSpeed(2.0f * pVehicle2->GetForward() / 3.0f); + CCarAI::AddPoliceCarOccupants(pVehicle2); + m_nLastTimeCreated = CTimer::GetTimeInMilliseconds(); + return; + } + } +} + +CVehicle* CSetPiece::TryToGenerateCopCar(CVector2D vSpawn, CVector2D vTarget) +{ + CVehicle* pVehicle = new CAutomobile(MI_POLICE, RANDOM_VEHICLE); + CVector pos(vSpawn.x, vSpawn.y, 1000.0f); + CColPoint point; + CEntity* pEntity; + if (CWorld::ProcessVerticalLine(pos, -1000.0f, point, pEntity, true, false, false, false, true, false, nil)) + pos.z = point.point.z + pVehicle->GetHeightAboveRoad(); + CVector vDirection(vTarget.x - vSpawn.x, vTarget.y - vSpawn.y, 0.0f); + vDirection.Normalise(); + pVehicle->GetForward() = CVector(vDirection.x, vDirection.y, 0.0f); + pVehicle->GetRight() = CVector(vDirection.y, -vDirection.x, 0.0f); + pVehicle->GetUp() = CVector(0.0f, 0.0f, 1.0f); + pVehicle->SetPosition(pos); + int16 total; + CWorld::FindObjectsKindaColliding(pos, pVehicle->GetColModel()->spheres->radius, false, &total, 16, nil, false, true, true, false, false); + if (total != 0) { + delete pVehicle; + return nil; + } + pVehicle->ChangeLawEnforcerState(true); + CWorld::Add(pVehicle); + return pVehicle; +} + +CCopPed* CSetPiece::TryToGenerateCopPed(CVector2D vSpawn) +{ + CCopPed* pCop = new CCopPed(COP_STREET); + CVector pos(vSpawn.x, vSpawn.y, 1000.0f); + CColPoint point; + CEntity* pEntity; + if (CWorld::ProcessVerticalLine(pos, -1000.0f, point, pEntity, true, false, false, false, true, false, nil)) + pos.z = point.point.z + 0.9f; + pCop->SetPosition(pos); + int16 total; + CWorld::FindObjectsKindaColliding(pos, pCop->GetColModel()->spheres->radius, false, &total, 16, nil, false, true, true, false, false); + if (total != 0) { + delete pCop; + return nil; + } + CWorld::Add(pCop); + return pCop; +} \ No newline at end of file diff --git a/src/control/SetPieces.h b/src/control/SetPieces.h new file mode 100644 index 00000000..5776d35a --- /dev/null +++ b/src/control/SetPieces.h @@ -0,0 +1,48 @@ +#pragma once + +#include "config.h" + +class CVehicle; +class CCopPed; + +enum eSetPieceType : uint8 +{ + SETPIECE_NONE = 0, + SETPIECE_TWOCOPCARSINALLEY, + SETPIECE_CARBLOCKINGPLAYERFROMSIDE, + SETPIECE_CARRAMMINGPLAYERFROMSIDE, + SETPIECE_CREATECOPPERONFOOT, + SETPIECE_CREATETWOCOPPERSONFOOT, + SETPIECE_TWOCARSBLOCKINGPLAYERFROMSIDE, + SETPIECE_TWOCARSRAMMINGPLAYERFROMSIDE +}; + +class CSetPiece +{ +public: + eSetPieceType m_nType; + uint32 m_nLastTimeCreated; + CVector2D m_vTriggerInf; + CVector2D m_vTriggerSup; + CVector2D m_vSpawn1; + CVector2D m_vSpawn2; + CVector2D m_vTarget1; + CVector2D m_vTarget2; + + CVehicle* TryToGenerateCopCar(CVector2D, CVector2D); + CCopPed* TryToGenerateCopPed(CVector2D); + void Update(void); +}; + +class CSetPieces +{ + static bool bDebug; + static uint32 NumSetPieces; + static CSetPiece aSetPieces[NUM_SETPIECES]; +public: + static void Init(void); + static void AddOne(uint8 type, CVector2D, CVector2D, CVector2D, CVector2D, CVector2D, CVector2D); + static void Save(uint8*, uint32*); + static void Load(uint8*, uint32); + static void Update(void); +}; diff --git a/src/control/TrafficLights.cpp b/src/control/TrafficLights.cpp index 500d6af2..54c97d06 100644 --- a/src/control/TrafficLights.cpp +++ b/src/control/TrafficLights.cpp @@ -108,6 +108,7 @@ CTrafficLights::DisplayActualLight(CEntity *ent) CBrightLights::RegisterOne(pos1, ent->GetUp(), ent->GetRight(), CVector(0.0f, 0.0f, 0.0f), id + BRIGHTLIGHT_TRAFFIC_GREEN); CBrightLights::RegisterOne(pos2, ent->GetUp(), -ent->GetRight(), CVector(0.0f, 0.0f, 0.0f), id + BRIGHTLIGHT_TRAFFIC_GREEN); +/* static const float top = -0.127f; static const float bot = -0.539f; static const float mid = bot + (top-bot)/3.0f; @@ -131,6 +132,7 @@ CTrafficLights::DisplayActualLight(CEntity *ent) 1.0f, 0.5f, 0.0f, 0.5f, 1.0f, 1.0f, 0.0f, 1.0f, SHINYTEXT_WALK, 255, 255, 255, 60.0f); } +*/ } void @@ -145,7 +147,7 @@ CTrafficLights::ScanForLightsOnMap(void) CPtrList &list = CWorld::GetSector(x, y)->m_lists[ENTITYLIST_DUMMIES]; for(node = list.first; node; node = node->next){ CEntity *light = (CEntity*)node->item; - if(light->GetModelIndex() != MI_TRAFFICLIGHTS) + if (!IsTrafficLight(light->GetModelIndex())) continue; // Check cars diff --git a/src/core/Cam.cpp b/src/core/Cam.cpp index afa153f9..d04e8683 100644 --- a/src/core/Cam.cpp +++ b/src/core/Cam.cpp @@ -29,7 +29,7 @@ bool PrintDebugCode = false; int16 DebugCamMode; #ifdef FREE_CAM -bool CCamera::bFreeCam = true; +bool CCamera::bFreeCam; int nPreviousMode = -1; #endif @@ -504,11 +504,11 @@ CCam::ProcessSpecialHeightRoutines(void) switch(((CPhysical*)CamTargetEntity)->m_nSurfaceTouched) case SURFACE_GRASS: - case SURFACE_DIRT: - case SURFACE_DIRTTRACK: - case SURFACE_STEEL: - case SURFACE_TIRE: - case SURFACE_STONE: + case SURFACE_GRAVEL: + case SURFACE_MUD_DRY: + case SURFACE_THICK_METAL_PLATE: + case SURFACE_RUBBER: + case SURFACE_STEEP_CLIFF: OnRoad = true; if(CCullZones::PlayerNoRain()) @@ -565,9 +565,9 @@ CCam::ProcessSpecialHeightRoutines(void) if(PreviouslyFailedRoadHeightCheck && m_fCloseInPedHeightOffset < 0.0001f){ if(colPoint.surfaceB != SURFACE_TARMAC && colPoint.surfaceB != SURFACE_GRASS && - colPoint.surfaceB != SURFACE_DIRT && - colPoint.surfaceB != SURFACE_DIRTTRACK && - colPoint.surfaceB != SURFACE_STONE){ + colPoint.surfaceB != SURFACE_GRAVEL && + colPoint.surfaceB != SURFACE_MUD_DRY && + colPoint.surfaceB != SURFACE_STEEP_CLIFF){ if(m_fRoadOffSet > 1.4f) m_fRoadOffSet = 1.4f; }else{ @@ -1408,11 +1408,11 @@ CCam::Process_FollowPed(const CVector &CameraTarget, float TargetOrientation, fl bool foo = false; switch(((CPhysical*)CamTargetEntity)->m_nSurfaceTouched) case SURFACE_GRASS: - case SURFACE_DIRT: + case SURFACE_GRAVEL: case SURFACE_PAVEMENT: - case SURFACE_STEEL: - case SURFACE_TIRE: - case SURFACE_STONE: + case SURFACE_THICK_METAL_PLATE: + case SURFACE_RUBBER: + case SURFACE_STEEP_CLIFF: foo = true; if(foo) WellBufferMe(TargetHeight, &m_fCamBufferedHeight, &m_fCamBufferedHeightSpeed, 0.4f, 0.05f, false); @@ -1596,7 +1596,7 @@ CCam::Process_FollowPedWithMouse(const CVector &CameraTarget, float TargetOrient CWorld::pIgnoreEntity = nil; float ViewPlaneHeight = Tan(DEGTORAD(FOV) / 2.0f); - float ViewPlaneWidth = ViewPlaneHeight * CDraw::FindAspectRatio() * fTweakFOV; + float ViewPlaneWidth = ViewPlaneHeight * CDraw::CalculateAspectRatio() * fTweakFOV; float Near = RwCameraGetNearClipPlane(Scene.camera); float radius = ViewPlaneWidth*Near; entity = CWorld::TestSphereAgainstWorld(Source + Front*Near, radius, nil, true, true, false, true, false, false); @@ -1750,8 +1750,8 @@ CCam::WorkOutCamHeightWeeCar(CVector &TargetCoors, float TargetOrientation) else WellBufferMe(TargetZOffSet, &RoadHeightFix, &RoadHeightFixSpeed, 0.27f, 0.1f, false); - if((colpoint.surfaceB == SURFACE_DEFAULT || colpoint.surfaceB >= SURFACE_METAL6) && - colpoint.surfaceB != SURFACE_STEEL && colpoint.surfaceB != SURFACE_STONE && + if((colpoint.surfaceB == SURFACE_DEFAULT || colpoint.surfaceB >= SURFACE_CAR) && + colpoint.surfaceB != SURFACE_THICK_METAL_PLATE && colpoint.surfaceB != SURFACE_STEEP_CLIFF && RoadHeightFix > 1.4f) RoadHeightFix = 1.4f; @@ -2429,7 +2429,7 @@ CCam::Process_Rocket(const CVector &CameraTarget, float, float, float) ResetStatics = false; } - ((CPed*)CamTargetEntity)->m_pedIK.GetComponentPosition(&HeadPos, PED_HEAD); + ((CPed*)CamTargetEntity)->m_pedIK.GetComponentPosition(HeadPos, PED_HEAD); Source = HeadPos; Source.z += 0.1f; Source.x -= 0.19f*Cos(m_fInitialPlayerOrientation); @@ -2568,7 +2568,7 @@ CCam::Process_M16_1stPerson(const CVector &CameraTarget, float, float, float) HeadPos.x = 0.0f; HeadPos.y = 0.0f; HeadPos.z = 0.0f; - ((CPed*)CamTargetEntity)->m_pedIK.GetComponentPosition(&HeadPos, PED_HEAD); + ((CPed*)CamTargetEntity)->m_pedIK.GetComponentPosition(HeadPos, PED_HEAD); Source = HeadPos; Source.z += 0.1f; Source.x -= 0.19f * Cos(m_fInitialPlayerOrientation); @@ -2657,7 +2657,7 @@ CCam::Process_1stPerson(const CVector &CameraTarget, float TargetOrientation, fl ResetStatics = false; } - ((CPed*)CamTargetEntity)->m_pedIK.GetComponentPosition(&HeadPos, PED_HEAD); + ((CPed*)CamTargetEntity)->m_pedIK.GetComponentPosition(HeadPos, PED_HEAD); Source = HeadPos; Source.z += 0.1f; Source.x -= 0.19f*Cos(m_fInitialPlayerOrientation); @@ -2925,7 +2925,7 @@ CCam::Process_Sniper(const CVector &CameraTarget, float TargetOrientation, float ResetStatics = false; } - ((CPed*)CamTargetEntity)->m_pedIK.GetComponentPosition(&HeadPos, PED_HEAD); + ((CPed*)CamTargetEntity)->m_pedIK.GetComponentPosition(HeadPos, PED_HEAD); Source = HeadPos; Source.z += 0.1f; Source.x -= 0.19f*Cos(m_fInitialPlayerOrientation); @@ -3630,7 +3630,7 @@ CCam::Process_Fixed(const CVector &CameraTarget, float, float, float) if(TheCamera.m_bUseSpecialFovTrain) FOV = TheCamera.m_fFovForTrain; - if(CMenuManager::m_ControlMethod == 0 && Using3rdPersonMouseCam()){ + if(FrontEndMenuManager.m_ControlMethod == 0 && Using3rdPersonMouseCam()){ CPed *player = FindPlayerPed(); if(player && player->CanStrafeOrMouseControl()){ float Heading = Front.Heading(); @@ -4574,7 +4574,7 @@ CCam::Process_FollowPed_Rotation(const CVector &CameraTarget, float TargetOrient CWorld::pIgnoreEntity = nil; float ViewPlaneHeight = Tan(DEGTORAD(FOV) / 2.0f); - float ViewPlaneWidth = ViewPlaneHeight * CDraw::FindAspectRatio() * fTweakFOV; + float ViewPlaneWidth = ViewPlaneHeight * CDraw::CalculateAspectRatio() * fTweakFOV; float Near = RwCameraGetNearClipPlane(Scene.camera); float radius = ViewPlaneWidth*Near; entity = CWorld::TestSphereAgainstWorld(Source + Front*Near, radius, nil, true, true, false, true, false, false); diff --git a/src/core/Camera.cpp b/src/core/Camera.cpp index 623b2ea9..b65b60f3 100644 --- a/src/core/Camera.cpp +++ b/src/core/Camera.cpp @@ -61,6 +61,8 @@ enum CCamera TheCamera; bool CCamera::m_bUseMouse3rdPerson = true; bool bDidWeProcessAnyCinemaCam; +float CCamera::m_f3rdPersonCHairMultX; +float CCamera::m_f3rdPersonCHairMultY; #ifdef IMPROVED_CAMERA #define KEYJUSTDOWN(k) ControlsManager.GetIsKeyboardKeyJustDown((RsKeyCodes)k) @@ -80,10 +82,6 @@ CCamera::CCamera(void) Init(); } -CCamera::CCamera(float) -{ -} - void CCamera::Init(void) { @@ -91,12 +89,7 @@ CCamera::Init(void) float fMouseAccelHorzntl = m_fMouseAccelHorzntl; float fMouseAccelVertical = m_fMouseAccelVertical; #endif -#ifdef FIX_BUGS - static const CCamera DummyCamera = CCamera(0.f); - *this = DummyCamera; -#else - memset(this, 0, sizeof(CCamera)); // getting rid of vtable, eh? -#endif + memset(this, 0, sizeof(CCamera)); // this is fine, no vtable #ifdef GTA3_1_1_PATCH m_fMouseAccelHorzntl = fMouseAccelHorzntl; m_fMouseAccelVertical = fMouseAccelVertical; @@ -3044,33 +3037,25 @@ CCamera::SetNearClipScript(float clip) void CCamera::ProcessFade(void) { - float fade = (CTimer::GetTimeInMilliseconds() - m_uiFadeTimeStarted)/1000.0f; - // Why even set CDraw::FadeValue if m_fFLOATingFade sets it anyway? if(m_bFading){ if(m_iFadingDirection == FADE_IN){ if(m_fTimeToFadeOut != 0.0f){ - m_fFLOATingFade = 255.0f - 255.0f*fade/m_fTimeToFadeOut; - if(m_fFLOATingFade <= 0.0f){ - m_bFading = false; - CDraw::FadeValue = 0; - m_fFLOATingFade = 0.0f; - } + m_fFLOATingFade -= CTimer::GetTimeStepInSeconds() * 255.0f / m_fTimeToFadeOut; }else{ + m_fFLOATingFade = 0.0f; + } + if (m_fFLOATingFade <= 0.0f) { m_bFading = false; - CDraw::FadeValue = 0; m_fFLOATingFade = 0.0f; } }else if(m_iFadingDirection == FADE_OUT){ if(m_fTimeToFadeOut != 0.0f){ - m_fFLOATingFade = 255.0f*fade/m_fTimeToFadeOut; - if(m_fFLOATingFade >= 255.0f){ - m_bFading = false; - CDraw::FadeValue = 255; - m_fFLOATingFade = 255.0f; - } + m_fFLOATingFade += CTimer::GetTimeStepInSeconds() * 255.0f / m_fTimeToFadeOut; }else{ + m_fFLOATingFade = 255.0f; + } + if (m_fFLOATingFade >= 255.0f) { m_bFading = false; - CDraw::FadeValue = 255; m_fFLOATingFade = 255.0f; } } @@ -3132,15 +3117,6 @@ CCamera::Fade(float timeout, int16 direction) m_iMusicFadingDirection = direction; m_fTimeToFadeMusic = timeout; m_uiFadeTimeStartedMusic = CTimer::GetTimeInMilliseconds(); -// Not on PS2 - if(!m_bJustJumpedOutOf1stPersonBecauseOfTarget && m_iMusicFadingDirection == FADE_OUT){ - unknown++; - if(unknown >= 2){ - m_bJustJumpedOutOf1stPersonBecauseOfTarget = true; - unknown = 0; - }else - m_bMoveCamToAvoidGeom = true; - } } } @@ -3217,7 +3193,7 @@ CCamera::GetLookDirection(void) Cams[ActiveCam].Mode == CCam::MODE_BEHINDBOAT || Cams[ActiveCam].Mode == CCam::MODE_FOLLOWPED) return Cams[ActiveCam].DirectionWasLooking; - return LOOKING_FORWARD;; + return LOOKING_FORWARD; } bool @@ -3305,6 +3281,18 @@ CCamera::Find3rdPersonQuickAimPitch(void) return -(DEGTORAD(((0.5f - m_f3rdPersonCHairMultY) * 1.8f * 0.5f * Cams[ActiveCam].FOV)) + rot); } +bool +CCamera::Using1stPersonWeaponMode(void) +{ + switch(PlayerWeaponMode.Mode) + case CCam::MODE_SNIPER: + case CCam::MODE_M16_1STPERSON: + case CCam::MODE_ROCKETLAUNCHER: + case CCam::MODE_HELICANNON_1STPERSON: + case CCam::MODE_CAMERA: + return true; + return false; +} void @@ -3329,8 +3317,9 @@ CCamera::CalculateDerivedValues(void) // left plane m_vecFrustumNormals[1] = CVector(-c, -s, 0.0f); - c /= CDraw::FindAspectRatio(); - s /= CDraw::FindAspectRatio(); + CDraw::CalculateAspectRatio(); + c /= SCREEN_ASPECT_RATIO; + s /= SCREEN_ASPECT_RATIO; // bottom plane m_vecFrustumNormals[2] = CVector(0.0f, -s, -c); // top plane diff --git a/src/core/Camera.h b/src/core/Camera.h index 80fc878e..4e90855b 100644 --- a/src/core/Camera.h +++ b/src/core/Camera.h @@ -91,7 +91,9 @@ public: MODE_M16_1STPERSON_RUNABOUT, MODE_FIGHT_CAM_RUNABOUT, MODE_EDITOR, - MODE_HELICANNON_1STPERSON, // vice city leftover + MODE_HELICANNON_1STPERSON, + MODE_45, + MODE_CAMERA, }; bool bBelowMinDist; //used for follow ped mode @@ -472,8 +474,8 @@ public: // not static yet float m_fMouseAccelHorzntl;// acceleration multiplier for 1st person controls float m_fMouseAccelVertical;// acceleration multiplier for 1st person controls - float m_f3rdPersonCHairMultX; - float m_f3rdPersonCHairMultY; + static float m_f3rdPersonCHairMultX; + static float m_f3rdPersonCHairMultY; CCam Cams[3]; @@ -549,7 +551,6 @@ public: // High level and misc CCamera(void); - CCamera(float); void Init(void); void Process(void); void CamControl(void); @@ -626,6 +627,7 @@ public: void UpdateAimingCoors(CVector const &coors); void Find3rdPersonCamTargetVector(float dist, CVector pos, CVector &source, CVector &target); float Find3rdPersonQuickAimPitch(void); + bool Using1stPersonWeaponMode(void); // Physical camera void SetRwCamera(RwCamera *cam); diff --git a/src/core/ColStore.cpp b/src/core/ColStore.cpp index 80bbdc77..070967e5 100644 --- a/src/core/ColStore.cpp +++ b/src/core/ColStore.cpp @@ -178,7 +178,7 @@ CColStore::LoadCollision(const CVector2D &pos) }else{ for (int j = 0; j < MAX_CLEANUP; j++) { CPhysical* pEntity = CTheScripts::MissionCleanup.DoesThisEntityWaitForCollision(j); - if (pEntity /* !pEntity->bDontLoadCollision && !pEntity->bIsFrozen */) { + if (pEntity && !pEntity->bDontLoadCollision && !pEntity->bIsFrozen) { if (GetBoundingBox(i).IsPointInside(pEntity->GetPosition(), -80.0f)) wantThisOne = true; } diff --git a/src/core/Collision.cpp b/src/core/Collision.cpp index c29c1d28..b68214af 100644 --- a/src/core/Collision.cpp +++ b/src/core/Collision.cpp @@ -414,8 +414,9 @@ CCollision::TestSphereTriangle(const CColSphere &sphere, return dist < sphere.radius; } +//--MIAMI: TODO bool -CCollision::TestLineOfSight(const CColLine &line, const CMatrix &matrix, CColModel &model, bool ignoreSeeThrough) +CCollision::TestLineOfSight(const CColLine &line, const CMatrix &matrix, CColModel &model, bool ignoreSeeThrough, bool ignoreShootThrough) { static CMatrix matTransform; int i; @@ -429,18 +430,18 @@ CCollision::TestLineOfSight(const CColLine &line, const CMatrix &matrix, CColMod return false; for(i = 0; i < model.numSpheres; i++) - if(!ignoreSeeThrough || model.spheres[i].surface != SURFACE_GLASS && model.spheres[i].surface != SURFACE_SCAFFOLD) + if(!ignoreSeeThrough || model.spheres[i].surface != SURFACE_GLASS && model.spheres[i].surface != SURFACE_TRANSPARENT_CLOTH) if(TestLineSphere(newline, model.spheres[i])) return true; for(i = 0; i < model.numBoxes; i++) - if(!ignoreSeeThrough || model.boxes[i].surface != SURFACE_GLASS && model.boxes[i].surface != SURFACE_SCAFFOLD) + if(!ignoreSeeThrough || model.boxes[i].surface != SURFACE_GLASS && model.boxes[i].surface != SURFACE_TRANSPARENT_CLOTH) if(TestLineBox(newline, model.boxes[i])) return true; CalculateTrianglePlanes(&model); for(i = 0; i < model.numTriangles; i++) - if(!ignoreSeeThrough || model.triangles[i].surface != SURFACE_GLASS && model.triangles[i].surface != SURFACE_SCAFFOLD) + if(!ignoreSeeThrough || model.triangles[i].surface != SURFACE_GLASS && model.triangles[i].surface != SURFACE_TRANSPARENT_CLOTH) if(TestLineTriangle(newline, model.vertices, model.triangles[i], model.trianglePlanes[i])) return true; @@ -1042,10 +1043,11 @@ CCollision::ProcessSphereTriangle(const CColSphere &sphere, return true; } +//--MIAMI: TODO bool CCollision::ProcessLineOfSight(const CColLine &line, const CMatrix &matrix, CColModel &model, - CColPoint &point, float &mindist, bool ignoreSeeThrough) + CColPoint &point, float &mindist, bool ignoreSeeThrough, bool ignoreShootThrough) { static CMatrix matTransform; int i; @@ -1060,16 +1062,16 @@ CCollision::ProcessLineOfSight(const CColLine &line, float coldist = mindist; for(i = 0; i < model.numSpheres; i++) - if(!ignoreSeeThrough || model.spheres[i].surface != SURFACE_GLASS && model.spheres[i].surface != SURFACE_SCAFFOLD) + if(!ignoreSeeThrough || model.spheres[i].surface != SURFACE_GLASS && model.spheres[i].surface != SURFACE_TRANSPARENT_CLOTH) ProcessLineSphere(newline, model.spheres[i], point, coldist); for(i = 0; i < model.numBoxes; i++) - if(!ignoreSeeThrough || model.boxes[i].surface != SURFACE_GLASS && model.boxes[i].surface != SURFACE_SCAFFOLD) + if(!ignoreSeeThrough || model.boxes[i].surface != SURFACE_GLASS && model.boxes[i].surface != SURFACE_TRANSPARENT_CLOTH) ProcessLineBox(newline, model.boxes[i], point, coldist); CalculateTrianglePlanes(&model); for(i = 0; i < model.numTriangles; i++) - if(!ignoreSeeThrough || model.triangles[i].surface != SURFACE_GLASS && model.triangles[i].surface != SURFACE_SCAFFOLD) + if(!ignoreSeeThrough || model.triangles[i].surface != SURFACE_GLASS && model.triangles[i].surface != SURFACE_TRANSPARENT_CLOTH) ProcessLineTriangle(newline, model.vertices, model.triangles[i], model.trianglePlanes[i], point, coldist); if(coldist < mindist){ @@ -1081,10 +1083,11 @@ CCollision::ProcessLineOfSight(const CColLine &line, return false; } +//--MIAMI: TODO bool CCollision::ProcessVerticalLine(const CColLine &line, const CMatrix &matrix, CColModel &model, - CColPoint &point, float &mindist, bool ignoreSeeThrough, CStoredCollPoly *poly) + CColPoint &point, float &mindist, bool ignoreSeeThrough, bool ignoreShootThrough, CStoredCollPoly *poly) { static CStoredCollPoly TempStoredPoly; int i; @@ -1100,17 +1103,17 @@ CCollision::ProcessVerticalLine(const CColLine &line, float coldist = mindist; for(i = 0; i < model.numSpheres; i++) - if(!ignoreSeeThrough || model.spheres[i].surface != SURFACE_GLASS && model.spheres[i].surface != SURFACE_SCAFFOLD) + if(!ignoreSeeThrough || model.spheres[i].surface != SURFACE_GLASS && model.spheres[i].surface != SURFACE_TRANSPARENT_CLOTH) ProcessLineSphere(newline, model.spheres[i], point, coldist); for(i = 0; i < model.numBoxes; i++) - if(!ignoreSeeThrough || model.boxes[i].surface != SURFACE_GLASS && model.boxes[i].surface != SURFACE_SCAFFOLD) + if(!ignoreSeeThrough || model.boxes[i].surface != SURFACE_GLASS && model.boxes[i].surface != SURFACE_TRANSPARENT_CLOTH) ProcessLineBox(newline, model.boxes[i], point, coldist); CalculateTrianglePlanes(&model); TempStoredPoly.valid = false; for(i = 0; i < model.numTriangles; i++) - if(!ignoreSeeThrough || model.triangles[i].surface != SURFACE_GLASS && model.triangles[i].surface != SURFACE_SCAFFOLD) + if(!ignoreSeeThrough || model.triangles[i].surface != SURFACE_GLASS && model.triangles[i].surface != SURFACE_TRANSPARENT_CLOTH) ProcessVerticalLineTriangle(newline, model.vertices, model.triangles[i], model.trianglePlanes[i], point, coldist, &TempStoredPoly); if(coldist < mindist){ @@ -1639,15 +1642,15 @@ CCollision::DrawColModel_Coloured(const CMatrix &mat, const CColModel &colModel, b *= f; } - if(s == SURFACE_SCAFFOLD || s == SURFACE_METAL_FENCE || - s == SURFACE_BOLLARD || s == SURFACE_METAL_POLE) + if(s == SURFACE_TRANSPARENT_CLOTH || s == SURFACE_METAL_CHAIN_FENCE || + s == SURFACE_TRANSPARENT_STONE || s == SURFACE_SCAFFOLD_POLE) if(CTimer::GetFrameCounter() & 1){ r = 0; g = 0; b = 0; } - if(s > SURFACE_GATE){ + if(s > SURFACE_METAL_GATE){ r = CGeneral::GetRandomNumber(); g = CGeneral::GetRandomNumber(); b = CGeneral::GetRandomNumber(); @@ -1720,8 +1723,8 @@ CCollision::DrawColModel_Coloured(const CMatrix &mat, const CColModel &colModel, b *= f; } - if(s == SURFACE_SCAFFOLD || s == SURFACE_METAL_FENCE || - s == SURFACE_BOLLARD || s == SURFACE_METAL_POLE) + if(s == SURFACE_TRANSPARENT_CLOTH || s == SURFACE_METAL_CHAIN_FENCE || + s == SURFACE_TRANSPARENT_STONE || s == SURFACE_SCAFFOLD_POLE) if(CTimer::GetFrameCounter() & 1){ r = 0; g = 0; diff --git a/src/core/Collision.h b/src/core/Collision.h index 4b0c2fb9..12af5225 100644 --- a/src/core/Collision.h +++ b/src/core/Collision.h @@ -151,7 +151,7 @@ public: static bool TestLineTriangle(const CColLine &line, const CVector *verts, const CColTriangle &tri, const CColTrianglePlane &plane); static bool TestLineSphere(const CColLine &line, const CColSphere &sph); static bool TestSphereTriangle(const CColSphere &sphere, const CVector *verts, const CColTriangle &tri, const CColTrianglePlane &plane); - static bool TestLineOfSight(const CColLine &line, const CMatrix &matrix, CColModel &model, bool ignoreSeeThrough); + static bool TestLineOfSight(const CColLine &line, const CMatrix &matrix, CColModel &model, bool ignoreSeeThrough, bool ignoreShootThrough); static bool ProcessSphereSphere(const CColSphere &s1, const CColSphere &s2, CColPoint &point, float &mindistsq); static bool ProcessSphereBox(const CColSphere &sph, const CColBox &box, CColPoint &point, float &mindistsq); @@ -160,8 +160,8 @@ public: static bool ProcessLineTriangle(const CColLine &line , const CVector *verts, const CColTriangle &tri, const CColTrianglePlane &plane, CColPoint &point, float &mindist); static bool ProcessLineSphere(const CColLine &line, const CColSphere &sphere, CColPoint &point, float &mindist); static bool ProcessSphereTriangle(const CColSphere &sph, const CVector *verts, const CColTriangle &tri, const CColTrianglePlane &plane, CColPoint &point, float &mindistsq); - static bool ProcessLineOfSight(const CColLine &line, const CMatrix &matrix, CColModel &model, CColPoint &point, float &mindist, bool ignoreSeeThrough); - static bool ProcessVerticalLine(const CColLine &line, const CMatrix &matrix, CColModel &model, CColPoint &point, float &mindist, bool ignoreSeeThrough, CStoredCollPoly *poly); + static bool ProcessLineOfSight(const CColLine &line, const CMatrix &matrix, CColModel &model, CColPoint &point, float &mindist, bool ignoreSeeThrough, bool ignoreShootThrough); + static bool ProcessVerticalLine(const CColLine &line, const CMatrix &matrix, CColModel &model, CColPoint &point, float &mindist, bool ignoreSeeThrough, bool ignoreShootThrough, CStoredCollPoly *poly); static int32 ProcessColModels(const CMatrix &matrixA, CColModel &modelA, const CMatrix &matrixB, CColModel &modelB, CColPoint *spherepoints, CColPoint *linepoints, float *linedists); static bool IsStoredPolyStillValidVerticalLine(const CVector &pos, float z, CColPoint &point, CStoredCollPoly *poly); diff --git a/src/core/ControllerConfig.cpp b/src/core/ControllerConfig.cpp index 6a5080e5..e48f2c3f 100644 --- a/src/core/ControllerConfig.cpp +++ b/src/core/ControllerConfig.cpp @@ -205,6 +205,8 @@ void CControllerConfigManager::InitDefaultControlConfiguration() SetControllerKeyAssociatedWithAction (PED_LOOKBEHIND, rsPADEND, KEYBOARD); SetControllerKeyAssociatedWithAction (PED_LOOKBEHIND, rsCAPSLK, OPTIONAL_EXTRA); + + SetControllerKeyAssociatedWithAction (PED_DUCK, 'C', KEYBOARD); SetControllerKeyAssociatedWithAction (PED_FIREWEAPON, rsPADINS, KEYBOARD); SetControllerKeyAssociatedWithAction (PED_FIREWEAPON, rsLCTRL, OPTIONAL_EXTRA); @@ -217,6 +219,8 @@ void CControllerConfigManager::InitDefaultControlConfiguration() SetControllerKeyAssociatedWithAction (PED_JUMPING, rsRCTRL, KEYBOARD); SetControllerKeyAssociatedWithAction (PED_JUMPING, ' ', OPTIONAL_EXTRA); + + SetControllerKeyAssociatedWithAction (PED_ANSWER_PHONE, rsTAB, KEYBOARD); if ( _dwOperatingSystemVersion == OS_WIN98 ) SetControllerKeyAssociatedWithAction(PED_SPRINT, rsSHIFT, OPTIONAL_EXTRA); // BUG: must be KEYBOARD ? @@ -259,7 +263,7 @@ void CControllerConfigManager::InitDefaultControlConfiguration() SetControllerKeyAssociatedWithAction (VEHICLE_TURRETDOWN, rsPADRIGHT, KEYBOARD); SetControllerKeyAssociatedWithAction (CAMERA_CHANGE_VIEW_ALL_SITUATIONS, rsHOME, KEYBOARD); - SetControllerKeyAssociatedWithAction (CAMERA_CHANGE_VIEW_ALL_SITUATIONS, 'C', OPTIONAL_EXTRA); + SetControllerKeyAssociatedWithAction (CAMERA_CHANGE_VIEW_ALL_SITUATIONS, 'V', OPTIONAL_EXTRA); for (int32 i = 0; i < MAX_SIMS; i++) { @@ -336,13 +340,14 @@ void CControllerConfigManager::InitDefaultControlConfigJoyPad(uint32 buttons) SetControllerKeyAssociatedWithAction(TOGGLE_SUBMISSIONS, 11, JOYSTICK); case 10: SetControllerKeyAssociatedWithAction(VEHICLE_HORN, 10, JOYSTICK); + SetControllerKeyAssociatedWithAction(PED_DUCK, 10, JOYSTICK); case 9: SetControllerKeyAssociatedWithAction(CAMERA_CHANGE_VIEW_ALL_SITUATIONS, 9, JOYSTICK); case 8: SetControllerKeyAssociatedWithAction(VEHICLE_HANDBRAKE, 8, JOYSTICK); SetControllerKeyAssociatedWithAction(PED_LOCK_TARGET, 8, JOYSTICK); case 7: - SetControllerKeyAssociatedWithAction(PED_CENTER_CAMERA_BEHIND_PLAYER, 7, JOYSTICK); + SetControllerKeyAssociatedWithAction(PED_ANSWER_PHONE, 7, JOYSTICK); SetControllerKeyAssociatedWithAction(VEHICLE_CHANGE_RADIO_STATION, 7, JOYSTICK); case 6: SetControllerKeyAssociatedWithAction(PED_CYCLE_WEAPON_RIGHT, 6, JOYSTICK); @@ -384,13 +389,14 @@ void CControllerConfigManager::InitDefaultControlConfigJoyPad(uint32 buttons) SetControllerKeyAssociatedWithAction(TOGGLE_SUBMISSIONS, 11, JOYSTICK); case 10: SetControllerKeyAssociatedWithAction(VEHICLE_HORN, 10, JOYSTICK); + SetControllerKeyAssociatedWithAction(PED_DUCK, 10, JOYSTICK); case 9: SetControllerKeyAssociatedWithAction(CAMERA_CHANGE_VIEW_ALL_SITUATIONS, 9, JOYSTICK); case 8: SetControllerKeyAssociatedWithAction(VEHICLE_HANDBRAKE, 8, JOYSTICK); SetControllerKeyAssociatedWithAction(PED_LOCK_TARGET, 8, JOYSTICK); case 7: - SetControllerKeyAssociatedWithAction(PED_CENTER_CAMERA_BEHIND_PLAYER, 7, JOYSTICK); + SetControllerKeyAssociatedWithAction(PED_ANSWER_PHONE, 7, JOYSTICK); SetControllerKeyAssociatedWithAction(VEHICLE_CHANGE_RADIO_STATION, 7, JOYSTICK); case 6: SetControllerKeyAssociatedWithAction(PED_CYCLE_WEAPON_RIGHT, 6, JOYSTICK); @@ -431,6 +437,8 @@ void CControllerConfigManager::InitialiseControllerActionNameArray() SETACTIONNAME(PED_CYCLE_TARGET_LEFT); SETACTIONNAME(PED_CYCLE_TARGET_RIGHT); SETACTIONNAME(PED_CENTER_CAMERA_BEHIND_PLAYER); + SETACTIONNAME(PED_DUCK); + SETACTIONNAME(PED_ANSWER_PHONE); SETACTIONNAME(VEHICLE_LOOKBEHIND); SETACTIONNAME(VEHICLE_LOOKLEFT); SETACTIONNAME(VEHICLE_LOOKRIGHT); @@ -754,6 +762,8 @@ void CControllerConfigManager::AffectControllerStateOn_ButtonDown_FirstPersonOnl state.Square = 255; if (button == GetControllerKeyAssociatedWithAction(PED_SNIPER_ZOOM_OUT, type)) state.Cross = 255; + if (button == GetControllerKeyAssociatedWithAction(PED_DUCK, type)) + state.RightShock = 255; } void CControllerConfigManager::AffectControllerStateOn_ButtonDown_ThirdPersonOnly(int32 button, eControllerType type, CControllerState &state) @@ -762,14 +772,18 @@ void CControllerConfigManager::AffectControllerStateOn_ButtonDown_ThirdPersonOnl state.RightShock = 255; if (button == GetControllerKeyAssociatedWithAction(PED_JUMPING, type)) state.Square = 255; + if (button == GetControllerKeyAssociatedWithAction(PED_ANSWER_PHONE, type)) + state.LeftShoulder1 = 255; if (button == GetControllerKeyAssociatedWithAction(PED_CYCLE_WEAPON_LEFT, type)) state.LeftShoulder2 = 255; if (button == GetControllerKeyAssociatedWithAction(PED_CYCLE_WEAPON_RIGHT, type)) state.RightShoulder2 = 255; if (button == GetControllerKeyAssociatedWithAction(PED_SPRINT, type)) state.Cross = 255; + if (button == GetControllerKeyAssociatedWithAction(PED_DUCK, type)) + state.RightShock = 255; - if (CMenuManager::m_ControlMethod == CONTROL_CLASSIC) + if (FrontEndMenuManager.m_ControlMethod == CONTROL_CLASSIC) { if (button == GetControllerKeyAssociatedWithAction(PED_CYCLE_TARGET_LEFT, type)) state.LeftShoulder2 = 255; @@ -835,7 +849,7 @@ void CControllerConfigManager::AffectControllerStateOn_ButtonDown_FirstAndThirdP state.RightStickX = 128; } - if (CMenuManager::m_ControlMethod == CONTROL_CLASSIC) + if (FrontEndMenuManager.m_ControlMethod == CONTROL_CLASSIC) { if (button == GetControllerKeyAssociatedWithAction(PED_1RST_PERSON_LOOK_UP, type)) { @@ -1616,8 +1630,12 @@ void CControllerConfigManager::DeleteMatching3rdPersonControls(e_ControllerActio ClearSettingsAssociatedWithAction(PED_JUMPING, type); if (key == GetControllerKeyAssociatedWithAction(PED_SPRINT, type)) ClearSettingsAssociatedWithAction(PED_SPRINT, type); + if (key == GetControllerKeyAssociatedWithAction(PED_DUCK, type)) + ClearSettingsAssociatedWithAction(PED_DUCK, type); + if (key == GetControllerKeyAssociatedWithAction(PED_ANSWER_PHONE, type)) + ClearSettingsAssociatedWithAction(PED_ANSWER_PHONE, type); - if (CMenuManager::m_ControlMethod == CONTROL_CLASSIC) + if (FrontEndMenuManager.m_ControlMethod == CONTROL_CLASSIC) { if (key == GetControllerKeyAssociatedWithAction(PED_CYCLE_TARGET_LEFT, type)) ClearSettingsAssociatedWithAction(PED_CYCLE_TARGET_LEFT, type); @@ -1640,7 +1658,7 @@ void CControllerConfigManager::DeleteMatching1rst3rdPersonControls(e_ControllerA if (key == GetControllerKeyAssociatedWithAction(GO_BACK, type)) ClearSettingsAssociatedWithAction(GO_BACK, type); - if (CMenuManager::m_ControlMethod == CONTROL_CLASSIC) + if (FrontEndMenuManager.m_ControlMethod == CONTROL_CLASSIC) { if (key == GetControllerKeyAssociatedWithAction(PED_1RST_PERSON_LOOK_LEFT, type)) ClearSettingsAssociatedWithAction(PED_1RST_PERSON_LOOK_LEFT, type); @@ -1803,6 +1821,8 @@ e_ControllerActionType CControllerConfigManager::GetActionType(e_ControllerActio case PED_CYCLE_WEAPON_RIGHT: case PED_JUMPING: case PED_SPRINT: + case PED_DUCK: + case PED_ANSWER_PHONE: case PED_CYCLE_TARGET_LEFT: case PED_CYCLE_TARGET_RIGHT: case PED_CENTER_CAMERA_BEHIND_PLAYER: diff --git a/src/core/ControllerConfig.h b/src/core/ControllerConfig.h index 7d0e1073..5f0b6862 100644 --- a/src/core/ControllerConfig.h +++ b/src/core/ControllerConfig.h @@ -32,6 +32,8 @@ enum e_ControllerAction PED_JUMPING, PED_SPRINT, PED_LOOKBEHIND, + PED_DUCK, + PED_ANSWER_PHONE, VEHICLE_ACCELERATE, VEHICLE_BRAKE, VEHICLE_CHANGE_RADIO_STATION, diff --git a/src/core/EventList.h b/src/core/EventList.h index 8840afc4..f2c3d7a8 100644 --- a/src/core/EventList.h +++ b/src/core/EventList.h @@ -22,10 +22,12 @@ enum eEventType EVENT_PED_SET_ON_FIRE, EVENT_COP_SET_ON_FIRE, EVENT_CAR_SET_ON_FIRE, - EVENT_ASSAULT_NASTYWEAPON, // not sure + EVENT_ASSAULT_NASTYWEAPON, + EVENT_ASSAULT_NASTYWEAPON_POLICE, EVENT_ICECREAM, EVENT_ATM, - EVENT_SHOPSTALL, // used on graffitis + EVENT_SHOPSTALL, + EVENT_SHOPWINDOW, EVENT_LAST_EVENT }; diff --git a/src/core/FileLoader.cpp b/src/core/FileLoader.cpp index e073b4cb..1463b4a5 100644 --- a/src/core/FileLoader.cpp +++ b/src/core/FileLoader.cpp @@ -1,4 +1,5 @@ #include "common.h" +#include #include "main.h" #include "Quaternion.h" @@ -26,6 +27,9 @@ #include "FileLoader.h" #include "Streaming.h" #include "ColStore.h" +#include "Occlusion.h" + +//--MIAMI: file done char CFileLoader::ms_line[256]; @@ -159,7 +163,6 @@ struct ColHeader uint32 size; }; -//--MIAMI: done void CFileLoader::LoadCollisionFile(const char *filename, uint8 colSlot) { @@ -196,7 +199,6 @@ CFileLoader::LoadCollisionFile(const char *filename, uint8 colSlot) } -//--MIAMI: done bool CFileLoader::LoadCollisionFileFirstTime(uint8 *buffer, uint32 size, uint8 colSlot) { @@ -298,13 +300,15 @@ CFileLoader::LoadCollisionModel(uint8 *buf, CColModel &model, char *modelname) model.numLines = *(int16*)buf; buf += 4; if(model.numLines > 0){ - model.lines = (CColLine*)RwMalloc(model.numLines*sizeof(CColLine)); + //model.lines = (CColLine*)RwMalloc(model.numLines*sizeof(CColLine)); for(i = 0; i < model.numLines; i++){ - model.lines[i].Set(*(CVector*)buf, *(CVector*)(buf+12)); + //model.lines[i].Set(*(CVector*)buf, *(CVector*)(buf+12)); buf += 24; } }else model.lines = nil; + model.numLines = 0; + model.lines = nil; model.numBoxes = *(int16*)buf; buf += 4; @@ -323,10 +327,12 @@ CFileLoader::LoadCollisionModel(uint8 *buf, CColModel &model, char *modelname) model.vertices = (CVector*)RwMalloc(numVertices*sizeof(CVector)); for(i = 0; i < numVertices; i++){ model.vertices[i] = *(CVector*)buf; +#if 0 if(Abs(model.vertices[i].x) >= 256.0f || Abs(model.vertices[i].y) >= 256.0f || Abs(model.vertices[i].z) >= 256.0f) printf("%s:Collision volume too big\n", modelname); +#endif buf += 12; } }else @@ -349,7 +355,7 @@ GetNameAndLOD(char *nodename, char *name, int *n) { char *underscore = nil; for(char *s = nodename; *s != '\0'; s++){ - if(s[0] == '_' && (s[1] == 'l' || s[1] == 'L')) + if(s[0] == '_' && (s[1] == 'l' || s[1] == 'L') && isdigit(s[2])) underscore = s; } if(underscore){ @@ -956,7 +962,7 @@ CFileLoader::LoadCarPathNode(const char *line, int id, int node, bool waterPath) void CFileLoader::Load2dEffect(const char *line) { - int id, r, g, b, a, type; + int id, r, g, b, a, type, ptype; float x, y, z; char corona[32], shadow[32]; int shadowIntens, lightType, roadReflection, flare, flags, probability; @@ -1029,6 +1035,18 @@ CFileLoader::Load2dEffect(const char *line) effect->attractor.flags = flags; effect->attractor.probability = probability; break; + case EFFECT_PED_ATTRACTOR: + sscanf(line, "%d %f %f %f %d %d %d %d %d %d %f %f %f %f %f %f", + &id, &x, &y, &z, &r, &g, &b, &a, &type, + &ptype, + &effect->pedattr.queueDir.x, + &effect->pedattr.queueDir.y, + &effect->pedattr.queueDir.z, + &effect->pedattr.useDir.x, + &effect->pedattr.useDir.y, + &effect->pedattr.useDir.z); + effect->pedattr.type = ptype; + break; } CTxdStore::PopCurrentTxd(); @@ -1081,7 +1099,7 @@ CFileLoader::LoadScene(const char *filename) LoadCullZone(line); break; case OCCL: - // TODO(MIAMI): occlusion + LoadOcclusionVolume(line); break; case PICK: // unused @@ -1175,7 +1193,9 @@ CFileLoader::LoadObjectInstance(const char *line) CColStore::GetBoundingBox(col->level).ContainRect(entity->GetBoundRect()); }else entity->bUsesCollision = false; - // TODO(MIAMI): set some flag here if col min is below 6 + + if(entity->GetPosition().z + col->boundingBox.min.z < 6.0f) + entity->bUnderwater = true; }else{ entity = new CDummyObject; entity->SetModelIndexNoCreate(id); @@ -1229,6 +1249,21 @@ CFileLoader::LoadPickup(const char *line) sscanf(line, "%d %f %f %f", &id, &x, &y, &z); } +void +CFileLoader::LoadOcclusionVolume(const char *line) +{ + float x, y, z; + float width, length, height; + float angle; + + sscanf(line, "%f %f %f %f %f %f %f", + &x, &y, &z, + &width, &length, &height, + &angle); + COcclusion::AddOne(x, y, z, width, length, z + height/2.0f, angle); +} + + //--MIAMI: unused void CFileLoader::ReloadPaths(const char *filename) diff --git a/src/core/FileLoader.h b/src/core/FileLoader.h index 584a2312..077e7bdd 100644 --- a/src/core/FileLoader.h +++ b/src/core/FileLoader.h @@ -39,6 +39,7 @@ public: static void LoadZone(const char *line); static void LoadCullZone(const char *line); static void LoadPickup(const char *line); + static void LoadOcclusionVolume(const char *line); static void ReloadPaths(const char *filename); static void ReloadObjectTypes(const char *filename); diff --git a/src/core/Frontend.cpp b/src/core/Frontend.cpp index d27a98ec..60a17aee 100644 --- a/src/core/Frontend.cpp +++ b/src/core/Frontend.cpp @@ -37,6 +37,22 @@ #include "Messages.h" #include "FileLoader.h" +// TODO(Miami): This is -3 on VC but still -1 on AudioManager?!? What the hell? +#define INVALID_AUDIO_PROVIDER -1 + +// Similar story to Hud.cpp: +// Game has colors inlined in code. +// For easier modification we collect them here: +CRGBA LABEL_COLOR(255, 150, 225, 255); +CRGBA SELECTIONBORDER_COLOR(25, 130, 70, 255); +CRGBA MENUOPTION_COLOR(255, 150, 225, 255); +CRGBA SELECTEDMENUOPTION_COLOR(255, 150, 225, 255); +CRGBA HEADER_COLOR(255, 150, 255, 255); +CRGBA DARKMENUOPTION_COLOR(195, 90, 165, 255); +CRGBA SLIDERON_COLOR(97, 194, 247, 255); +CRGBA SLIDEROFF_COLOR(27, 89, 130, 255); +CRGBA MAPINFOBOX_COLOR(255, 150, 225, 150); + #define TIDY_UP_PBP // ProcessButtonPresses #define MAX_VISIBLE_LIST_ROW 30 #define SCROLLBAR_MAX_HEIGHT 263.0f // not in end result @@ -66,14 +82,6 @@ #define GetBackJustDown GetSquareJustDown #endif -#ifdef MENU_MAP -bool CMenuManager::bMenuMapActive = false; -bool CMenuManager::bMapMouseShownOnce = false; -bool CMenuManager::bMapLoaded = false; -float CMenuManager::fMapSize; -float CMenuManager::fMapCenterY; -float CMenuManager::fMapCenterX; -#endif #ifdef PS2_LIKE_MENU BottomBarOption bbNames[8]; @@ -86,35 +94,8 @@ int curBottomBarOption = -1; int hoveredBottomBarOption = -1; #endif -int32 CMenuManager::OS_Language = LANG_ENGLISH; -int8 CMenuManager::m_PrefsUseVibration; -int8 CMenuManager::m_DisplayControllerOnFoot; -int8 CMenuManager::m_PrefsVsync = 1; -int8 CMenuManager::m_PrefsVsyncDisp = 1; -int8 CMenuManager::m_PrefsFrameLimiter = 1; -int8 CMenuManager::m_PrefsShowSubtitles = 1; -int8 CMenuManager::m_PrefsSpeakers; -int32 CMenuManager::m_ControlMethod; -int8 CMenuManager::m_PrefsDMA = 1; -int32 CMenuManager::m_PrefsLanguage; uint8 CMenuManager::m_PrefsStereoMono; // unused except restore settings -bool CMenuManager::m_PrefsAllowNastyGame = true; -bool CMenuManager::m_bStartUpFrontEndRequested; -bool CMenuManager::m_bShutDownFrontEndRequested; - -int8 CMenuManager::m_PrefsUseWideScreen; -int8 CMenuManager::m_PrefsRadioStation; -int32 CMenuManager::m_PrefsBrightness = 256; -float CMenuManager::m_PrefsLOD = CRenderer::ms_lodDistScale; -int8 CMenuManager::m_bFrontEnd_ReloadObrTxtGxt; -int32 CMenuManager::m_PrefsMusicVolume = 102; -int32 CMenuManager::m_PrefsSfxVolume = 102; - -char CMenuManager::m_PrefsSkinFile[256] = DEFAULT_SKIN_NAME; - -int32 CMenuManager::m_KeyPressedCode = -1; - // Originally that was PS2 option color, they forget it here and used in PrintBriefs once(but didn't use the output anyway) #ifdef PS2_LIKE_MENU const CRGBA TEXT_COLOR = CRGBA(150, 110, 30, 255); @@ -125,99 +106,53 @@ const CRGBA TEXT_COLOR = CRGBA(235, 170, 50, 255); // PC briefs text color float MENU_TEXT_SIZE_X = SMALLTEXT_X_SCALE; float MENU_TEXT_SIZE_Y = SMALLTEXT_Y_SCALE; -bool holdingScrollBar; // *(bool*)0x628D59; // not original name -int32 CMenuManager::m_SelectedMap; -int32 CMenuManager::m_SelectedGameType; - -// Used in a hidden menu -uint8 CMenuManager::m_PrefsPlayerRed = 255; -uint8 CMenuManager::m_PrefsPlayerGreen = 128; -uint8 CMenuManager::m_PrefsPlayerBlue; // why?? +bool holdingScrollBar; // *(bool*)0x7039B9; // not original name CMenuManager FrontEndMenuManager; +MenuTrapezoid menuBg(CGeneral::GetRandomNumber() % 40 + 65, CGeneral::GetRandomNumber() % 40 + 21, + CGeneral::GetRandomNumber() % 40 + 568, CGeneral::GetRandomNumber() % 40 + 44, + CGeneral::GetRandomNumber() % 40 + 36, CGeneral::GetRandomNumber() % 40 + 352, + CGeneral::GetRandomNumber() % 40 + 593, CGeneral::GetRandomNumber() % 40 + 312); -uint32 TimeToStopPadShaking; -char *pEditString; -int32 *pControlEdit; -bool DisplayComboButtonErrMsg; -int32 MouseButtonJustClicked; -int32 JoyButtonJustClicked; -//int32 *pControlTemp = 0; +MenuTrapezoid menuOptionHighlight(0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f); + +// TODO(Miami): TEMPORARY +bool bMapLoaded = false; +bool bMapMouseShownOnce = false; #ifndef MASTER bool CMenuManager::m_PrefsMarketing = false; bool CMenuManager::m_PrefsDisableTutorials = false; #endif // !MASTER -// 0x5F311C +// 0x68C144 const char* FrontendFilenames[][2] = { - {"fe2_mainpanel_ul", "" }, - {"fe2_mainpanel_ur", "" }, - {"fe2_mainpanel_dl", "" }, - {"fe2_mainpanel_dr", "" }, - {"fe2_mainpanel_dr2", "" }, - {"fe2_tabactive", "" }, - {"fe_iconbrief", "" }, - {"fe_iconstats", "" }, - {"fe_iconcontrols", "" }, - {"fe_iconsave", "" }, - {"fe_iconaudio", "" }, - {"fe_icondisplay", "" }, - {"fe_iconlanguage", "" }, - {"fe_controller", "" }, - {"fe_controllersh", "" }, - {"fe_arrows1", "" }, - {"fe_arrows2", "" }, - {"fe_arrows3", "" }, - {"fe_arrows4", "" }, - {"fe_radio1", "" }, - {"fe_radio2", "" }, - {"fe_radio3", "" }, - {"fe_radio4", "" }, - {"fe_radio5", "" }, - {"fe_radio6", "" }, - {"fe_radio7", "" }, - {"fe_radio8", "" }, - {"fe_radio9", "" }, -}; - -#ifdef MENU_MAP -const char* MapFilenames[][2] = { + {"background", ""}, + {"vc_logo", "vc_logom"}, + {"mouse", "mousea"}, + {"mapTop01", "mapTop01A"}, + {"mapTop02", "mapTop02A"}, + {"mapTop03", "mapTop03A"}, {"mapMid01", "mapMid01A"}, {"mapMid02", "mapMid02A"}, {"mapMid03", "mapMid03A"}, {"mapBot01", "mapBot01A"}, {"mapBot02", "mapBot02A"}, {"mapBot03", "mapBot03A"}, - {"mapTop01", "mapTop01A"}, - {"mapTop02", "mapTop02A"}, - {"mapTop03", "mapTop03A"}, -}; -CSprite2d CMenuManager::m_aMapSprites[NUM_MAP_SPRITES]; -#endif - -// 0x5F3344 -const char* MenuFilenames[][2] = { - {"connection24", ""}, - {"findgame24", ""}, - {"hostgame24", ""}, - {"mainmenu24", ""}, - {"Playersetup24", ""}, - {"singleplayer24", ""}, - {"multiplayer24", ""}, - {"dmalogo128", "dmalogo128m"}, - {"gtaLogo128", "gtaLogo128"}, - {"rockstarLogo128", "rockstarlogo128m"}, - {"gamespy256", "gamespy256a"}, - {"mouse", "mousetimera"}, - {"mousetimer", "mousetimera"}, - {"mp3logo", "mp3logoA"}, - {"downOFF", "buttonA"}, - {"downON", "buttonA"}, + {"wildstyle", "wildstyleA"}, + {"flash", "flashA"}, + {"kchat", "kchatA"}, + {"fever", "feverA"}, + {"vrock", "vrockA"}, + {"vcpr", "vcprA"}, + {"espantoso", "espantosoA"}, + {"emotion", "emotionA"}, + {"wave103", "wave103A"}, + {"mp3", "mp3A"}, + {"downOff", "buttonA"}, + {"downOn", "buttonA"}, {"upOff", "buttonA"}, - {"upON", "buttonA"}, - {"gta3logo256", "gta3logo256m"}, - { nil, nil } + {"upOn", "buttonA"} }; #ifdef ASPECT_RATIO_SCALE @@ -246,45 +181,8 @@ ScaleAndCenterX(float x) #define MENU_Y(y) StretchY(y) #endif -#ifdef PS2_LIKE_MENU -#define ChangeScreen(screen, option, updateDelay, withReverseAlpha) \ - do { \ - if (reverseAlpha) { \ - m_nPrevScreen = m_nCurrScreen; \ - m_nCurrScreen = pendingScreen; \ - m_nCurrOption = pendingOption; \ - reverseAlpha = false; \ - if (updateDelay) \ - m_nScreenChangeDelayTimer = CTimer::GetTimeInMillisecondsPauseMode(); \ - } \ - if (withReverseAlpha) { \ - pendingOption = option; \ - pendingScreen = screen; \ - reverseAlpha = true; \ - } else { \ - m_nPrevScreen = m_nCurrScreen; \ - m_nCurrScreen = screen; \ - m_nCurrOption = option; \ - if (updateDelay) \ - m_nScreenChangeDelayTimer = CTimer::GetTimeInMillisecondsPauseMode(); \ - } \ - m_nMenuFadeAlpha = 255; \ - } while(0) -#else -#define ChangeScreen(screen, option, updateDelay, clearAlpha) \ - do { \ - m_nPrevScreen = m_nCurrScreen; \ - m_nCurrScreen = screen; \ - m_nCurrOption = option; \ - if(updateDelay) \ - m_nScreenChangeDelayTimer = CTimer::GetTimeInMillisecondsPauseMode(); \ - if(clearAlpha) \ - m_nMenuFadeAlpha = 0; \ - } while(0) -#endif - #define PREPARE_MENU_HEADER \ - CFont::SetColor(CRGBA(0, 0, 0, FadeIn(255))); \ + CFont::SetColor(CRGBA(HEADER_COLOR.r, HEADER_COLOR.g, HEADER_COLOR.b, FadeIn(255))); \ CFont::SetRightJustifyOn(); \ CFont::SetScale(MENU_X(MENUHEADER_WIDTH), MENU_Y(MENUHEADER_HEIGHT)); \ CFont::SetFontStyle(FONT_LOCALE(FONT_HEADING)); @@ -306,15 +204,86 @@ ScaleAndCenterX(float x) m_nHoverOption = HOVEROPTION_NOT_HOVERING; \ } while(0) +// TODO: this is COMPLETELY different in VC #define ProcessRadioIcon(sprite, x, y, radioId, hoverOpt) \ do { \ - sprite.Draw(x, y, MENU_X(MENURADIO_ICON_SCALE), MENU_Y(MENURADIO_ICON_SCALE), radioId == m_PrefsRadioStation ? CRGBA(255, 255, 255, 255) : CRGBA(225, 0, 0, 170)); \ + sprite.Draw(x, y, MENU_X(MENURADIO_ICON_SCALE), MENU_Y(MENURADIO_ICON_SCALE), radioId == m_PrefsRadioStation ? CRGBA(255, 255, 255, 255) : CRGBA(255, 255, 255, 100)); \ if (CheckHover(x, x + MENU_X(MENURADIO_ICON_SCALE), y, y + MENU_Y(MENURADIO_ICON_SCALE))) \ m_nHoverOption = hoverOpt; \ } while (0) // --- Functions not in the game/inlined starts +bool DoRWStuffStartOfFrame(int16 TopRed, int16 TopGreen, int16 TopBlue, int16 BottomRed, int16 BottomGreen, int16 BottomBlue, int16 Alpha); +void DoRWStuffEndOfFrame(void); + +#ifdef PS2_LIKE_MENU +void +CMenuManager::SwitchToNewScreen(int8 screen) +{ + if (reverseAlpha) { + m_nPrevScreen = m_nCurrScreen; + m_nCurrScreen = pendingScreen; + m_nCurrOption = pendingOption; + reverseAlpha = false; + if (updateDelay) + m_LastScreenSwitch = CTimer::GetTimeInMillisecondsPauseMode(); + } + if (withReverseAlpha) { + pendingOption = option; + pendingScreen = screen; + reverseAlpha = true; + } else { + m_nPrevScreen = m_nCurrScreen; + m_nCurrScreen = screen; + m_nCurrOption = option; + if (updateDelay) + m_LastScreenSwitch = CTimer::GetTimeInMillisecondsPauseMode(); + } + m_nMenuFadeAlpha = 255; +} +#else + +// --MIAMI: Done except using VC's gMenuPages +void +CMenuManager::SwitchToNewScreen(int8 screen) +{ + bMenuChangeOngoing = true; + DoRWStuffStartOfFrame(0, 0, 0, 0, 0, 0, 255); + DrawBackground(true); + DoRWStuffEndOfFrame(); + DoRWStuffStartOfFrame(0, 0, 0, 0, 0, 0, 255); + DrawBackground(true); + DoRWStuffEndOfFrame(); + m_nPrevScreen = m_nCurrScreen; + m_ShowEmptyBindingError = false; + ResetHelperText(); + + ThingsToDoBeforeLeavingPage(); + + if (screen == -2) { + int oldScreen = !m_bGameNotLoaded ? aScreens[m_nCurrScreen].m_PreviousPage[1] : aScreens[m_nCurrScreen].m_PreviousPage[0]; + int oldOption = !m_bGameNotLoaded ? aScreens[m_nCurrScreen].m_ParentEntry[1] : + (m_nCurrScreen == MENUPAGE_NEW_GAME ? 0 : (m_nCurrScreen == MENUPAGE_OPTIONS ? 1 : (m_nCurrScreen == MENUPAGE_EXIT ? 2 : aScreens[m_nCurrScreen].m_ParentEntry[0]))); + + m_nCurrOption = oldOption; + m_nCurrScreen = oldScreen; + } else if (screen == 0) { + m_nCurrScreen = aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_TargetMenu; + m_nCurrOption = 0; + } else { + m_nCurrOption = 0; + m_nCurrScreen = screen; + } + + if (m_nCurrScreen == MENUPAGE_CHOOSE_SAVE_SLOT) + m_nCurrOption = 8; + m_nMenuFadeAlpha = 0; + bOptionHighlightTransitionBlend = 0; + m_LastScreenSwitch = CTimer::GetTimeInMilliseconds(); +} +#endif + inline void CMenuManager::ScrollUpListByOne() { @@ -381,13 +350,14 @@ CMenuManager::PageDownList(bool playSoundOnSuccess) } } +// TODO(Miami) inline void CMenuManager::ThingsToDoBeforeLeavingPage() { if ((m_nCurrScreen == MENUPAGE_SKIN_SELECT) && strcmp(m_aSkinName, m_PrefsSkinFile) != 0) { CWorld::Players[0].SetPlayerSkin(m_PrefsSkinFile); } else if (m_nCurrScreen == MENUPAGE_SOUND_SETTINGS) { - if (m_nPrefsAudio3DProviderIndex != -1) + if (m_nPrefsAudio3DProviderIndex != INVALID_AUDIO_PROVIDER) m_nPrefsAudio3DProviderIndex = DMAudio.GetCurrent3DProviderIndex(); #ifdef TIDY_UP_PBP DMAudio.StopFrontEndTrack(); @@ -411,6 +381,122 @@ CMenuManager::ThingsToDoBeforeLeavingPage() // ------ Functions not in the game/inlined ends +CMenuManager::CMenuManager() +{ + m_StatsScrollSpeed = 150.0f; + m_StatsScrollDirection = 1; + m_PrefsSfxVolume = 49; + m_PrefsMusicVolume = 49; + m_PrefsRadioStation = 0; + field_2C = 1; + m_PrefsBrightness = 256; + m_PrefsLOD = 1.2f; + m_KeyPressedCode = -1; + m_bFrontEnd_ReloadObrTxtGxt = false; + m_PrefsMP3BoostVolume = 0; + m_PrefsShowSubtitles = 0; + m_PrefsShowLegends = 1; + m_PrefsUseWideScreen = 0; + m_PrefsVsync = 0; + m_PrefsVsyncDisp = 1; + m_PrefsFrameLimiter = 1; + m_PrefsLanguage = 0; + field_54 = 0; + m_PrefsAllowNastyGame = 1; + m_PrefsSpeakers = 0; + field_8 = 0; + m_PrefsUseVibration = 0; + m_PrefsShowHud = 1; + m_PrefsRadarMode = 0; + field_10 = 0; + m_bShutDownFrontEndRequested = false; + m_bStartUpFrontEndRequested = false; + pEditString = nil; + pControlEdit = nil; + DisplayComboButtonErrMsg = false; + m_PrefsDMA = 1; + OS_Language = LANG_ENGLISH; + m_ControlMethod = CONTROL_STANDARD; + CCamera::m_bUseMouse3rdPerson = true; + m_lastWorking3DAudioProvider = 0; + m_nFirstVisibleRowOnList = 0; + m_nScrollbarTopMargin = 0.0f; + m_nSelectedListRow = 0; + m_nSkinsTotal = 0; + m_nPrefsAudio3DProviderIndex = -99; + m_bGameNotLoaded = true; + m_nMousePosX = m_nMouseTempPosX; + m_nMousePosY = m_nMouseTempPosY; + m_nMouseOldPosX = m_nMousePosX; + m_nMouseOldPosY = m_nMousePosY; + m_bShowMouse = true; + m_nHoverOption = HOVEROPTION_NOT_HOVERING; + + // TODO(Miami) + // DMAudio.SetMP3BoostVolume(m_PrefsMP3BoostVolume); + m_bMenuActive = false; + m_bActivateSaveMenu = false; + m_bWantToLoad = false; + m_nMenuFadeAlpha = 0; + m_OnlySaveMenu = false; + m_fMapSize = 162.0f; + m_fMapCenterX = 320.0f; + m_fMapCenterY = 225.0f; + DMAudio.SetMusicMasterVolume(m_PrefsMusicVolume); + DMAudio.SetEffectsMasterVolume(m_PrefsSfxVolume); +} + +void +CMenuManager::SetFrontEndRenderStates(void) +{ + RwRenderStateSet(rwRENDERSTATETEXTUREFILTER, (void*)rwFILTERLINEAR); + RwRenderStateSet(rwRENDERSTATETEXTUREADDRESS, (void*)rwTEXTUREADDRESSCLAMP); + RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void*)FALSE); + RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)FALSE); + RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDSRCALPHA); + RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCALPHA); + RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)TRUE); +} + +void +CMenuManager::Initialise(void) +{ + DoRWStuffStartOfFrame(0, 0, 0, 0, 0, 0, 255); + DoRWStuffEndOfFrame(); + m_AllowNavigation = false; + m_menuTransitionProgress = -50; + m_nMenuFadeAlpha = 0; + m_nCurrOption = 0; + bOptionHighlightTransitionBlend = 0; + CentreMousePointer(); + m_bShowMouse = true; + m_fMapSize = 162.0f; + m_fMapCenterX = 320.0f; + m_fMapCenterY = 225.0f; + CPad::StopPadsShaking(); + if (!m_OnlySaveMenu) + m_nCurrScreen = MENUPAGE_NONE; + DMAudio.ChangeMusicMode(MUSICMODE_FRONTEND); + DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_STARTING, 0); + DMAudio.Service(); + DMAudio.SetMusicMasterVolume(m_PrefsMusicVolume); + DMAudio.SetEffectsMasterVolume(m_PrefsSfxVolume); + m_PrefsRadioStation = DMAudio.GetRadioInCar(); + + // TODO(Miami) + // DMAudio.SetMP3BoostVolume(m_PrefsMP3BoostVolume); + if (DMAudio.IsMP3RadioChannelAvailable()) { + if (m_PrefsRadioStation < HEAD_RADIO || m_PrefsRadioStation > USERTRACK) + m_PrefsRadioStation = CGeneral::GetRandomNumber() % 10; + } else if (m_PrefsRadioStation < HEAD_RADIO || m_PrefsRadioStation > CHATTERBOX) + m_PrefsRadioStation = CGeneral::GetRandomNumber() % 9; + + CFileMgr::SetDir(""); + //CFileMgr::SetDir(""); + PcSaveHelper.PopulateSlotInfo(); + CTimer::StartUserPause(); +} + void CMenuManager::BuildStatLine(Const char *text, void *stat, bool itsFloat, void *stat2) { @@ -651,15 +737,15 @@ CMenuManager::DisplaySlider(float x, float y, float mostLeftBarSize, float mostR int lastActiveBarX = 0; float curBarX = 0.0f; - float spacing = SCREEN_SCALE_X(10.0f); + float spacing = SCREEN_SCALE_X(4.0f); // TODO: find actual numbers used in the game for (int i = 0; i < 16; i++) { - curBarX = i * rectSize/16.0f + x; + curBarX = i * rectSize/32.0f + x; if (i / 16.0f + 1 / 32.0f < progress) { - color = CRGBA(255, 217, 106, FadeIn(255)); + color = CRGBA(SLIDERON_COLOR.r, SLIDERON_COLOR.g, SLIDERON_COLOR.b, FadeIn(255)); lastActiveBarX = curBarX; } else - color = CRGBA(185, 120, 0, FadeIn(255)); + color = CRGBA(SLIDEROFF_COLOR.r, SLIDEROFF_COLOR.g, SLIDEROFF_COLOR.b, FadeIn(255)); maxBarHeight = Max(mostLeftBarSize, mostRightBarSize); @@ -684,33 +770,22 @@ CMenuManager::DoSettingsBeforeStartingAGame() DMAudio.Service(); m_bWantToRestart = true; - - ShutdownJustMenu(); - UnloadTextures(); + m_bShutDownFrontEndRequested = true; DMAudio.SetEffectsFadeVol(0); DMAudio.SetMusicFadeVol(0); + SwitchMenuOnAndOff(); DMAudio.ResetTimers(CTimer::GetTimeInMilliseconds()); } void -CMenuManager::Draw() +CMenuManager::DrawStandardMenus() { CFont::SetBackgroundOff(); CFont::SetPropOn(); CFont::SetCentreOff(); CFont::SetJustifyOn(); CFont::SetBackGroundOnlyTextOn(); -#ifdef GTA3_1_1_PATCH - CFont::SetColor(CRGBA(235, 170, 50, FadeIn(255))); - CFont::SetRightJustifyOn(); - CFont::SetFontStyle(FONT_HEADING); - CFont::SetScale(MENU_X(0.7f), MENU_Y(0.5f)); - CFont::SetWrapx(SCREEN_WIDTH); - CFont::SetRightJustifyWrap(0.0f); - strcpy(gString, "V1.1"); - AsciiToUnicode(gString, gUString); - CFont::PrintString(SCREEN_WIDTH / 10, SCREEN_HEIGHT / 45, gUString); -#endif + CFont::SetWrapx(MENU_X_RIGHT_ALIGNED(MENU_X_MARGIN)); CFont::SetRightJustifyWrap(SCREEN_SCALE_X(MENUACTION_WIDTH)); @@ -721,24 +796,20 @@ CMenuManager::Draw() case MENUPAGE_BRIEFS: PrintBriefs(); break; -#ifdef MENU_MAP - case MENUPAGE_MAP: - PrintMap(); - break; -#endif } // Header height isn't accounted, we will add that later. float nextYToUse = 40.0f; // Page name -#ifdef PS2_SAVE_DIALOG - if(!m_bRenderGameInMenu) -#endif if (aScreens[m_nCurrScreen].m_ScreenName[0] != '\0') { - + PREPARE_MENU_HEADER - CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(MENUHEADER_POS_X), SCREEN_SCALE_FROM_BOTTOM(MENUHEADER_POS_Y), TheText.Get(aScreens[m_nCurrScreen].m_ScreenName)); + CFont::SetColor(CRGBA(30, 30, 30, FadeIn(255))); + CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(MENUHEADER_POS_X + 7.f), SCREEN_SCALE_Y(MENUHEADER_POS_Y + 7.f), TheText.Get(aScreens[m_nCurrScreen].m_ScreenName)); + + PREPARE_MENU_HEADER + CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(MENUHEADER_POS_X), SCREEN_SCALE_Y(MENUHEADER_POS_Y), TheText.Get(aScreens[m_nCurrScreen].m_ScreenName)); // Weird place to put that. nextYToUse += 24.0f + 10.0f; @@ -747,7 +818,7 @@ CMenuManager::Draw() CFont::SetFontStyle(FONT_LOCALE(FONT_BANK)); CFont::SetScale(MENU_X(MENUACTION_SCALE_MULT * MENU_TEXT_SIZE_X), MENU_Y(MENUACTION_SCALE_MULT * MENU_TEXT_SIZE_Y)); CFont::SetRightJustifyOff(); - CFont::SetColor(CRGBA(235, 170, 50, FadeIn(255))); + CFont::SetColor(CRGBA(LABEL_COLOR.r, LABEL_COLOR.g, LABEL_COLOR.b, FadeIn(255))); // Label wchar *str; @@ -845,7 +916,7 @@ CMenuManager::Draw() break; case MENUPAGE_START_MENU: columnWidth = 320; - headerHeight = 140; + headerHeight = 110; lineHeight = 24; CFont::SetFontStyle(FONT_LOCALE(FONT_HEADING)); CFont::SetScale(MENU_X(MENU_TEXT_SIZE_X = BIGTEXT_X_SCALE), MENU_Y(MENU_TEXT_SIZE_Y = BIGTEXT_Y_SCALE)); @@ -859,15 +930,6 @@ CMenuManager::Draw() CFont::SetScale(MENU_X(MENU_TEXT_SIZE_X = BIGTEXT_X_SCALE), MENU_Y(MENU_TEXT_SIZE_Y = BIGTEXT_Y_SCALE)); CFont::SetCentreOn(); break; -#ifdef PS2_SAVE_DIALOG - case MENUPAGE_SAVE: - columnWidth = 180; - headerHeight = 60; - lineHeight = 24; - CFont::SetFontStyle(FONT_LOCALE(FONT_BANK)); - CFont::SetScale(MENU_X(MENU_TEXT_SIZE_X = BIGTEXT_X_SCALE), MENU_Y(MENU_TEXT_SIZE_Y = BIGTEXT_Y_SCALE)); - break; -#endif default: columnWidth = 320; headerHeight = 40; @@ -898,7 +960,7 @@ CMenuManager::Draw() } float usableLineHeight = lineHeight * 0.9f; // also height of biggest bar in slider - float smallestSliderBar = lineHeight * 0.1f; + float smallestSliderBar = lineHeight * 0.25f; // TODO: find actual number bool foundTheHoveringItem = false; wchar unicodeTemp[64]; char asciiTemp[32]; @@ -943,73 +1005,8 @@ CMenuManager::Draw() } switch (aScreens[m_nCurrScreen].m_aEntries[i].m_Action) { - case MENUACTION_CHANGEMENU: { - switch (aScreens[m_nCurrScreen].m_aEntries[i].m_TargetMenu) { - case MENUPAGE_MULTIPLAYER_MAP: - switch (m_SelectedMap) { - case 0: - rightText = TheText.Get("FEM_MA0"); - break; - case 1: - rightText = TheText.Get("FEM_MA1"); - break; - case 2: - rightText = TheText.Get("FEM_MA2"); - break; - case 3: - rightText = TheText.Get("FEM_MA3"); - break; - case 4: - rightText = TheText.Get("FEM_MA4"); - break; - case 5: - rightText = TheText.Get("FEM_MA5"); - break; - case 6: - rightText = TheText.Get("FEM_MA6"); - break; - case 7: - rightText = TheText.Get("FEM_MA7"); - break; - default: - break; - } - break; - case MENUPAGE_MULTIPLAYER_MODE: - switch (m_SelectedGameType) { - case 0: - rightText = TheText.Get("FEN_TY0"); - break; - case 1: - rightText = TheText.Get("FEN_TY1"); - break; - case 2: - rightText = TheText.Get("FEN_TY2"); - break; - case 3: - rightText = TheText.Get("FEN_TY3"); - break; - case 4: - rightText = TheText.Get("FEN_TY4"); - break; - case 5: - rightText = TheText.Get("FEN_TY5"); - break; - case 6: - rightText = TheText.Get("FEN_TY6"); - break; - case 7: - rightText = TheText.Get("FEN_TY7"); - break; - default: - break; - } - break; - default: - break; - } + case MENUACTION_CHANGEMENU: break; - } case MENUACTION_CTRLVIBRATION: if (m_PrefsUseVibration) rightText = TheText.Get("FEM_ON"); @@ -1032,12 +1029,6 @@ CMenuManager::Draw() break; } break; - case MENUACTION_CTRLDISPLAY: - if (m_DisplayControllerOnFoot) - rightText = TheText.Get("FEC_ONF"); - else - rightText = TheText.Get("FEC_INC"); - break; case MENUACTION_FRAMESYNC: rightText = TheText.Get(m_PrefsVsyncDisp ? "FEM_ON" : "FEM_OFF"); break; @@ -1117,7 +1108,7 @@ CMenuManager::Draw() break; #endif case MENUACTION_AUDIOHW: - if (m_nPrefsAudio3DProviderIndex == -1) + if (m_nPrefsAudio3DProviderIndex == INVALID_AUDIO_PROVIDER) rightText = TheText.Get("FEA_NAH"); else { char *provider = DMAudio.Get3DProviderName(m_nPrefsAudio3DProviderIndex); @@ -1132,7 +1123,7 @@ CMenuManager::Draw() } break; case MENUACTION_SPEAKERCONF: { - if (m_nPrefsAudio3DProviderIndex == -1) + if (m_nPrefsAudio3DProviderIndex == INVALID_AUDIO_PROVIDER) rightText = TheText.Get("FEA_NAH"); else { switch (m_PrefsSpeakers) { @@ -1219,14 +1210,11 @@ CMenuManager::Draw() } // Green bar behind selected option -#ifdef PS2_SAVE_DIALOG - if (!m_bRenderGameInMenu) -#endif if (i == m_nCurrOption && itemsAreSelectable) { // We keep stretching, because we also stretch background image and we want that bar to be aligned with borders of background CSprite2d::DrawRect(CRect(StretchX(10.0f), MENU_Y(bitAboveNextItemY), SCREEN_STRETCH_FROM_RIGHT(11.0f), MENU_Y(usableLineHeight + nextItemY)), - CRGBA(100, 200, 50, FadeIn(50))); + CRGBA(SELECTIONBORDER_COLOR.r, SELECTIONBORDER_COLOR.g, SELECTIONBORDER_COLOR.b, FadeIn(255))); } CFont::SetColor(CRGBA(0, 0, 0, FadeIn(90))); @@ -1245,14 +1233,14 @@ CMenuManager::Draw() if(!strcmp(aScreens[m_nCurrScreen].m_aEntries[i].m_EntryName, "FED_RES") && !m_bGameNotLoaded && textLayer == 1) { - CFont::SetColor(CRGBA(155, 117, 6, FadeIn(255))); + CFont::SetColor(CRGBA(DARKMENUOPTION_COLOR.r, DARKMENUOPTION_COLOR.g, DARKMENUOPTION_COLOR.b, FadeIn(255))); } CFont::PrintString(MENU_X_RIGHT_ALIGNED(columnWidth - textLayer), itemY, rightText); } if (i == m_nCurrOption && itemsAreSelectable){ - CFont::SetColor(CRGBA(255, 217, 106, FadeIn(255))); + CFont::SetColor(CRGBA(MENUOPTION_COLOR.r, MENUOPTION_COLOR.g, MENUOPTION_COLOR.b, FadeIn(255))); } else { - CFont::SetColor(CRGBA(235, 170, 50, FadeIn(255))); + CFont::SetColor(CRGBA(SELECTEDMENUOPTION_COLOR.r, SELECTEDMENUOPTION_COLOR.g, SELECTEDMENUOPTION_COLOR.b, FadeIn(255))); } } @@ -1274,7 +1262,7 @@ CMenuManager::Draw() } if (m_nPrefsAudio3DProviderIndex != DMAudio.GetCurrent3DProviderIndex()) { if (strcmp(aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_EntryName, "FEA_3DH") != 0 - && m_nCurrScreen == MENUPAGE_SOUND_SETTINGS && m_nPrefsAudio3DProviderIndex != -1) { + && m_nCurrScreen == MENUPAGE_SOUND_SETTINGS && m_nPrefsAudio3DProviderIndex != INVALID_AUDIO_PROVIDER) { m_nPrefsAudio3DProviderIndex = DMAudio.GetCurrent3DProviderIndex(); SetHelperText(3); @@ -1321,18 +1309,18 @@ CMenuManager::Draw() // Radio icons if (aScreens[m_nCurrScreen].m_aEntries[i].m_Action == MENUACTION_RADIO) { - ProcessRadioIcon(m_aFrontEndSprites[FE_RADIO1], MENU_X_LEFT_ALIGNED(30.0f), MENU_Y(nextYToUse), 0, HOVEROPTION_RADIO_0); - ProcessRadioIcon(m_aFrontEndSprites[FE_RADIO2], MENU_X_LEFT_ALIGNED(90.0f), MENU_Y(nextYToUse), 1, HOVEROPTION_RADIO_1); - ProcessRadioIcon(m_aFrontEndSprites[FE_RADIO5], MENU_X_LEFT_ALIGNED(150.0f), MENU_Y(nextYToUse), 2, HOVEROPTION_RADIO_2); - ProcessRadioIcon(m_aFrontEndSprites[FE_RADIO7], MENU_X_LEFT_ALIGNED(210.0f), MENU_Y(nextYToUse), 3, HOVEROPTION_RADIO_3); - ProcessRadioIcon(m_aFrontEndSprites[FE_RADIO8], MENU_X_LEFT_ALIGNED(270.0f), MENU_Y(nextYToUse), 4, HOVEROPTION_RADIO_4); - ProcessRadioIcon(m_aFrontEndSprites[FE_RADIO3], MENU_X_LEFT_ALIGNED(320.0f), MENU_Y(nextYToUse), 5, HOVEROPTION_RADIO_5); - ProcessRadioIcon(m_aFrontEndSprites[FE_RADIO4], MENU_X_LEFT_ALIGNED(360.0f), MENU_Y(nextYToUse), 6, HOVEROPTION_RADIO_6); - ProcessRadioIcon(m_aFrontEndSprites[FE_RADIO6], MENU_X_LEFT_ALIGNED(420.0f), MENU_Y(nextYToUse), 7, HOVEROPTION_RADIO_7); - ProcessRadioIcon(m_aFrontEndSprites[FE_RADIO9], MENU_X_LEFT_ALIGNED(480.0f), MENU_Y(nextYToUse), 8, HOVEROPTION_RADIO_8); + ProcessRadioIcon(m_aFrontEndSprites[MENUSPRITE_WILDSTYLE], MENU_X_LEFT_ALIGNED(30.0f), MENU_Y(nextYToUse), 0, HOVEROPTION_RADIO_0); + ProcessRadioIcon(m_aFrontEndSprites[MENUSPRITE_FLASH], MENU_X_LEFT_ALIGNED(90.0f), MENU_Y(nextYToUse), 1, HOVEROPTION_RADIO_1); + ProcessRadioIcon(m_aFrontEndSprites[MENUSPRITE_KCHAT], MENU_X_LEFT_ALIGNED(150.0f), MENU_Y(nextYToUse), 2, HOVEROPTION_RADIO_2); + ProcessRadioIcon(m_aFrontEndSprites[MENUSPRITE_FEVER], MENU_X_LEFT_ALIGNED(210.0f), MENU_Y(nextYToUse), 3, HOVEROPTION_RADIO_3); + ProcessRadioIcon(m_aFrontEndSprites[MENUSPRITE_VROCK], MENU_X_LEFT_ALIGNED(270.0f), MENU_Y(nextYToUse), 4, HOVEROPTION_RADIO_4); + ProcessRadioIcon(m_aFrontEndSprites[MENUSPRITE_VCPR], MENU_X_LEFT_ALIGNED(320.0f), MENU_Y(nextYToUse), 5, HOVEROPTION_RADIO_5); + ProcessRadioIcon(m_aFrontEndSprites[MENUSPRITE_ESPANTOSO], MENU_X_LEFT_ALIGNED(360.0f), MENU_Y(nextYToUse), 6, HOVEROPTION_RADIO_6); + ProcessRadioIcon(m_aFrontEndSprites[MENUSPRITE_EMOTION], MENU_X_LEFT_ALIGNED(420.0f), MENU_Y(nextYToUse), 7, HOVEROPTION_RADIO_7); + ProcessRadioIcon(m_aFrontEndSprites[MENUSPRITE_WAVE], MENU_X_LEFT_ALIGNED(480.0f), MENU_Y(nextYToUse), 8, HOVEROPTION_RADIO_8); if (DMAudio.IsMP3RadioChannelAvailable()) - ProcessRadioIcon(m_aMenuSprites[MENUSPRITE_MP3LOGO], MENU_X_LEFT_ALIGNED(540.0f), MENU_Y(nextYToUse), 9, HOVEROPTION_RADIO_9); + ProcessRadioIcon(m_aFrontEndSprites[MENUSPRITE_MP3], MENU_X_LEFT_ALIGNED(540.0f), MENU_Y(nextYToUse), 9, HOVEROPTION_RADIO_9); nextYToUse += 70.0f; } @@ -1349,14 +1337,6 @@ CMenuManager::Draw() DisplayHelperText(); break; } - - if (m_nCurrScreen == MENUPAGE_CONTROLLER_SETTINGS) - PrintController(); - else if (m_nCurrScreen == MENUPAGE_SKIN_SELECT_OLD) { - CSprite2d::DrawRect(CRect(MENU_X_LEFT_ALIGNED(180), MENU_Y(98), MENU_X_LEFT_ALIGNED(230), MENU_Y(123)), CRGBA(255, 255, 255, FadeIn(255))); - CSprite2d::DrawRect(CRect(MENU_X_LEFT_ALIGNED(181), MENU_Y(99), MENU_X_LEFT_ALIGNED(229), MENU_Y(122)), CRGBA(m_PrefsPlayerRed, m_PrefsPlayerGreen, m_PrefsPlayerBlue, FadeIn(255))); - } - } int @@ -1813,11 +1793,21 @@ CMenuManager::DrawControllerSetupScreen() switch (m_ControlMethod) { case CONTROL_STANDARD: - CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(MENUHEADER_POS_X), SCREEN_SCALE_FROM_BOTTOM(MENUHEADER_POS_Y), + CFont::SetColor(CRGBA(30, 30, 30, FadeIn(255))); + CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(MENUHEADER_POS_X + 7.f), SCREEN_SCALE_Y(MENUHEADER_POS_Y + 7.f), + TheText.Get(aScreens[m_nCurrScreen].m_ScreenName)); + + PREPARE_MENU_HEADER + CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(MENUHEADER_POS_X), SCREEN_SCALE_Y(MENUHEADER_POS_Y), TheText.Get(aScreens[m_nCurrScreen].m_ScreenName)); break; case CONTROL_CLASSIC: - CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(MENUHEADER_POS_X), SCREEN_SCALE_FROM_BOTTOM(MENUHEADER_POS_Y), + CFont::SetColor(CRGBA(30, 30, 30, FadeIn(255))); + CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(MENUHEADER_POS_X + 7.f), SCREEN_SCALE_Y(MENUHEADER_POS_Y + 7.f), + TheText.Get("FET_CTI")); + + PREPARE_MENU_HEADER + CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(MENUHEADER_POS_X), SCREEN_SCALE_Y(MENUHEADER_POS_Y), TheText.Get("FET_CTI")); break; default: @@ -1994,6 +1984,10 @@ void CMenuManager::DrawFrontEnd() { CFont::SetAlphaFade(255.0f); + CSprite2d::InitPerFrame(); + CFont::InitPerFrame(); + SetFrontEndRenderStates(); + m_NoEmptyBinding = true; #ifdef PS2_LIKE_MENU if (m_nCurrScreen == MENUPAGE_NONE) { @@ -2037,63 +2031,15 @@ CMenuManager::DrawFrontEnd() if (m_nCurrOption == 0 && aScreens[m_nCurrScreen].m_aEntries[0].m_Action == MENUACTION_LABEL) m_nCurrOption = 1; -#ifdef PS2_SAVE_DIALOG - if(m_bRenderGameInMenu) - DrawFrontEndSaveZone(); - else -#endif - DrawFrontEndNormal(); + if (m_menuTransitionProgress == 255 && m_nMenuFadeAlpha == 255) + bMenuChangeOngoing = false; - PrintErrorMessage(); + DrawBackground(false); } -#ifdef PS2_SAVE_DIALOG -void -CMenuManager::DrawFrontEndSaveZone() -{ - CSprite2d::InitPerFrame(); - CFont::InitPerFrame(); - RwRenderStateSet(rwRENDERSTATETEXTUREFILTER, (void*)rwFILTERNEAREST); - - // Not original dimensions, have been changed to fit PC screen & PC menu layout. - CSprite2d::DrawRect(CRect(MENU_X_LEFT_ALIGNED(30.0f), MENU_Y(50.0f), MENU_X_RIGHT_ALIGNED(30.0f), SCREEN_SCALE_FROM_BOTTOM(50.0f)), CRGBA(0, 0, 0, 175)); - - m_nMenuFadeAlpha = 255; - RwRenderStateSet(rwRENDERSTATETEXTUREADDRESS, (void*)rwTEXTUREADDRESSCLAMP); - RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)FALSE); - Draw(); - - CFont::DrawFonts(); - - // Draw mouse - RwRenderStateSet(rwRENDERSTATETEXTUREFILTER, (void*)rwFILTERLINEAR); - RwRenderStateSet(rwRENDERSTATETEXTUREADDRESS, (void*)rwTEXTUREADDRESSCLAMP); - if (m_bShowMouse) { - RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDSRCALPHA); - RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCALPHA); - RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)TRUE); - - CRect mouse(0.0f, 0.0f, MENU_X(75.0f), MENU_Y(75.0f)); - CRect shad(MENU_X(10.0f), MENU_Y(3.0f), MENU_X(85.0f), MENU_Y(78.0f)); - - mouse.Translate(m_nMousePosX, m_nMousePosY); - shad.Translate(m_nMousePosX, m_nMousePosY); - if(field_518 == 4){ - m_aMenuSprites[MENUSPRITE_MOUSET].Draw(shad, CRGBA(100, 100, 100, 50)); - RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)FALSE); - m_aMenuSprites[MENUSPRITE_MOUSET].Draw(mouse, CRGBA(255, 255, 255, 255)); - }else{ - m_aMenuSprites[MENUSPRITE_MOUSE].Draw(shad, CRGBA(100, 100, 100, 50)); - RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)FALSE); - m_aMenuSprites[MENUSPRITE_MOUSE].Draw(mouse, CRGBA(255, 255, 255, 255)); - } - } -} -#endif - #ifdef PS2_LIKE_MENU void -CMenuManager::DrawFrontEndNormal() +CMenuManager::DrawBackground() { CSprite2d::InitPerFrame(); CFont::InitPerFrame(); @@ -2210,7 +2156,7 @@ CMenuManager::DrawFrontEndNormal() DrawControllerSetupScreen(); break; default: - Draw(); + DrawStandardMenus(); break; } @@ -2273,168 +2219,200 @@ CMenuManager::DrawFrontEndNormal() mouse.Translate(m_nMousePosX, m_nMousePosY); shad.Translate(m_nMousePosX, m_nMousePosY); if(field_518 == 4){ - m_aMenuSprites[MENUSPRITE_MOUSET].Draw(shad, CRGBA(100, 100, 100, 50)); + m_aFrontEndSprites[MENUSPRITE_MOUSET].Draw(shad, CRGBA(100, 100, 100, 50)); RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)FALSE); - m_aMenuSprites[MENUSPRITE_MOUSET].Draw(mouse, CRGBA(255, 255, 255, 255)); + m_aFrontEndSprites[MENUSPRITE_MOUSET].Draw(mouse, CRGBA(255, 255, 255, 255)); }else{ - m_aMenuSprites[MENUSPRITE_MOUSE].Draw(shad, CRGBA(100, 100, 100, 50)); + m_aFrontEndSprites[MENUSPRITE_MOUSE].Draw(shad, CRGBA(100, 100, 100, 50)); RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)FALSE); - m_aMenuSprites[MENUSPRITE_MOUSE].Draw(mouse, CRGBA(255, 255, 255, 255)); + m_aFrontEndSprites[MENUSPRITE_MOUSE].Draw(mouse, CRGBA(255, 255, 255, 255)); } } } #else + +// --MIAMI: Done except commented things void -CMenuManager::DrawFrontEndNormal() +CMenuManager::DrawBackground(bool transitionCall) { - CSprite2d::InitPerFrame(); - CFont::InitPerFrame(); - RwRenderStateSet(rwRENDERSTATETEXTUREFILTER, (void*)rwFILTERLINEAR); + if (!m_bSpritesLoaded) + return; - LoadSplash(nil); - - eMenuSprites previousSprite; - if (m_nMenuFadeAlpha < 255) { - switch (m_nPrevScreen) { - case MENUPAGE_STATS: - case MENUPAGE_START_MENU: - case MENUPAGE_PAUSE_MENU: - previousSprite = MENUSPRITE_MAINMENU; - break; - case MENUPAGE_NEW_GAME: - case MENUPAGE_CHOOSE_LOAD_SLOT: - case MENUPAGE_CHOOSE_DELETE_SLOT: - case MENUPAGE_NEW_GAME_RELOAD: - case MENUPAGE_LOAD_SLOT_CONFIRM: - case MENUPAGE_DELETE_SLOT_CONFIRM: - case MENUPAGE_EXIT: - previousSprite = MENUSPRITE_SINGLEPLAYER; - break; - case MENUPAGE_MULTIPLAYER_MAIN: - previousSprite = MENUSPRITE_MULTIPLAYER; - break; - case MENUPAGE_MULTIPLAYER_MAP: - case MENUPAGE_MULTIPLAYER_FIND_GAME: - case MENUPAGE_SKIN_SELECT: - case MENUPAGE_KEYBOARD_CONTROLS: - case MENUPAGE_MOUSE_CONTROLS: - previousSprite = MENUSPRITE_FINDGAME; - break; - case MENUPAGE_MULTIPLAYER_CONNECTION: - case MENUPAGE_MULTIPLAYER_MODE: - previousSprite = MENUSPRITE_CONNECTION; - break; - case MENUPAGE_MULTIPLAYER_CREATE: - previousSprite = MENUSPRITE_HOSTGAME; - break; - case MENUPAGE_SKIN_SELECT_OLD: - case MENUPAGE_OPTIONS: - previousSprite = MENUSPRITE_PLAYERSET; - break; - default: - previousSprite = MENUSPRITE_MAINMENU; - break; - } - - if (m_nPrevScreen == m_nCurrScreen) - CSprite2d::DrawRect(CRect(0.0f, 0.0f, SCREEN_WIDTH, SCREEN_HEIGHT), CRGBA(0, 0, 0, 255 - m_nMenuFadeAlpha)); - else - m_aMenuSprites[previousSprite].Draw(CRect(0.0f, 0.0f, SCREEN_WIDTH, SCREEN_HEIGHT), CRGBA(255, 255, 255, 255 - m_nMenuFadeAlpha)); + SetFrontEndRenderStates(); + + if (m_menuTransitionProgress < 255) { + CSprite2d::DrawRect(CRect(0.0f, 0.0f, SCREEN_WIDTH, SCREEN_HEIGHT), CRGBA(0, 0, 0, 255)); } - RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void*)FALSE); - RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)FALSE); + if (m_nMenuFadeAlpha != 0) { - eMenuSprites currentSprite = MENUSPRITE_MAINMENU; // actually uninitialized - switch (m_nCurrScreen) { - case MENUPAGE_STATS: - case MENUPAGE_START_MENU: - case MENUPAGE_PAUSE_MENU: - currentSprite = MENUSPRITE_MAINMENU; - break; - case MENUPAGE_NEW_GAME: - case MENUPAGE_CHOOSE_LOAD_SLOT: - case MENUPAGE_CHOOSE_DELETE_SLOT: - case MENUPAGE_NEW_GAME_RELOAD: - case MENUPAGE_LOAD_SLOT_CONFIRM: - case MENUPAGE_DELETE_SLOT_CONFIRM: - case MENUPAGE_EXIT: - currentSprite = MENUSPRITE_SINGLEPLAYER; - break; - case MENUPAGE_MULTIPLAYER_MAIN: - currentSprite = MENUSPRITE_MULTIPLAYER; - break; - case MENUPAGE_MULTIPLAYER_MAP: - case MENUPAGE_MULTIPLAYER_FIND_GAME: - case MENUPAGE_SKIN_SELECT: - case MENUPAGE_KEYBOARD_CONTROLS: - case MENUPAGE_MOUSE_CONTROLS: - currentSprite = MENUSPRITE_FINDGAME; - break; - case MENUPAGE_MULTIPLAYER_CONNECTION: - case MENUPAGE_MULTIPLAYER_MODE: - currentSprite = MENUSPRITE_CONNECTION; - break; - case MENUPAGE_MULTIPLAYER_CREATE: - currentSprite = MENUSPRITE_HOSTGAME; - break; - case MENUPAGE_SKIN_SELECT_OLD: - case MENUPAGE_OPTIONS: - currentSprite = MENUSPRITE_PLAYERSET; - break; - } + if (m_nMenuFadeAlpha < 255) { - if (m_nMenuFadeAlpha < 255) { + menuBg.Translate(m_nMenuFadeAlpha); + SetFrontEndRenderStates(); + m_aFrontEndSprites[MENUSPRITE_BACKGROUND].Draw(CRect(0.0f, 0.0f, SCREEN_WIDTH, SCREEN_HEIGHT), CRGBA(255, 255, 255, FadeIn(255))); + if (m_nCurrScreen == MENUPAGE_MAP) + PrintMap(); - // Famous transparent menu bug -#ifdef FIX_BUGS - static float fadeAlpha = 0.0f; - if (m_nMenuFadeAlpha == 0 && fadeAlpha > 1.0f) fadeAlpha = 0.0f; + // Left border + CSprite2d::Draw2DPolygon(SCREEN_STRETCH_X(menuBg.bottomLeft_x), SCREEN_STRETCH_Y(menuBg.bottomLeft_y), 0.0f, SCREEN_HEIGHT, + SCREEN_STRETCH_X(menuBg.topLeft_x), SCREEN_STRETCH_Y(menuBg.topLeft_y), 0.0f, 0.0f, CRGBA(0, 0, 0, 255)); - // +20 per every 33 ms (1000.f/30.f - original frame limiter fps) - fadeAlpha += (frameTime) * 20.f / 33.f; - m_nMenuFadeAlpha = fadeAlpha; -#else - static uint32 LastFade = 0; + // Top border + CSprite2d::Draw2DPolygon(SCREEN_STRETCH_X(menuBg.topRight_x), SCREEN_STRETCH_Y(menuBg.topRight_y), + SCREEN_STRETCH_X(menuBg.topLeft_x), SCREEN_STRETCH_Y(menuBg.topLeft_y), SCREEN_WIDTH, 0.0f, 0.0f, 0.0f, CRGBA(0, 0, 0, 255)); - if(CTimer::GetTimeInMillisecondsPauseMode() - LastFade > 10){ - m_nMenuFadeAlpha += 20; - LastFade = CTimer::GetTimeInMillisecondsPauseMode(); - } -#endif - - if (m_nMenuFadeAlpha > 255){ - m_aMenuSprites[currentSprite].Draw(CRect(0.0f, 0.0f, SCREEN_WIDTH, SCREEN_HEIGHT), CRGBA(255, 255, 255, 255)); + // Bottom border + CSprite2d::Draw2DPolygon(SCREEN_WIDTH, SCREEN_HEIGHT, 0.0f, SCREEN_HEIGHT, SCREEN_STRETCH_X(menuBg.bottomRight_x), SCREEN_STRETCH_Y(menuBg.bottomRight_y), + SCREEN_STRETCH_X(menuBg.bottomLeft_x), SCREEN_STRETCH_Y(menuBg.bottomLeft_y), CRGBA(0, 0, 0, 255)); + + // Right border + CSprite2d::Draw2DPolygon(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_STRETCH_X(menuBg.bottomRight_x), SCREEN_STRETCH_Y(menuBg.bottomRight_y), + SCREEN_WIDTH, 0.0f, SCREEN_STRETCH_X(menuBg.topRight_x), SCREEN_STRETCH_Y(menuBg.topRight_y), CRGBA(0, 0, 0, 255)); } else { - RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)TRUE); - m_aMenuSprites[currentSprite].Draw(CRect(0.0f, 0.0f, SCREEN_WIDTH, SCREEN_HEIGHT), CRGBA(255, 255, 255, m_nMenuFadeAlpha)); + m_nMenuFadeAlpha = 255; + m_menuTransitionProgress = 255; + m_aFrontEndSprites[MENUSPRITE_BACKGROUND].Draw(CRect(0.0f, 0.0f, SCREEN_WIDTH, SCREEN_HEIGHT), CRGBA(255, 255, 255, FadeIn(255))); + if (m_nCurrScreen == MENUPAGE_MAP) + PrintMap(); + + // Left border + CSprite2d::Draw2DPolygon(SCREEN_STRETCH_X(menuBg.bottomLeft_x), SCREEN_STRETCH_Y(menuBg.bottomLeft_y), 0.0f, SCREEN_HEIGHT, + SCREEN_STRETCH_X(menuBg.topLeft_x), SCREEN_STRETCH_Y(menuBg.topLeft_y), 0.0f, 0.0f, CRGBA(0, 0, 0, 255)); + + // Top border + CSprite2d::Draw2DPolygon(SCREEN_STRETCH_X(menuBg.topRight_x), SCREEN_STRETCH_Y(menuBg.topRight_y), + SCREEN_STRETCH_X(menuBg.topLeft_x), SCREEN_STRETCH_Y(menuBg.topLeft_y), SCREEN_WIDTH, 0.0f, 0.0f, 0.0f, CRGBA(0, 0, 0, 255)); + + // Bottom border + CSprite2d::Draw2DPolygon(SCREEN_WIDTH, SCREEN_HEIGHT, 0.0f, SCREEN_HEIGHT, SCREEN_STRETCH_X(menuBg.bottomRight_x), SCREEN_STRETCH_Y(menuBg.bottomRight_y), + SCREEN_STRETCH_X(menuBg.bottomLeft_x), SCREEN_STRETCH_Y(menuBg.bottomLeft_y), CRGBA(0, 0, 0, 255)); + + // Right border + CSprite2d::Draw2DPolygon(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_STRETCH_X(menuBg.bottomRight_x), SCREEN_STRETCH_Y(menuBg.bottomRight_y), + SCREEN_WIDTH, 0.0f, SCREEN_STRETCH_X(menuBg.topRight_x), SCREEN_STRETCH_Y(menuBg.topRight_y), CRGBA(0, 0, 0, 255)); } } else { - m_aMenuSprites[currentSprite].Draw(CRect(0.0f, 0.0f, SCREEN_WIDTH, SCREEN_HEIGHT), CRGBA(255, 255, 255, 255)); - // TODO: what is this? waiting mouse? - if(field_518 == 4){ - if(m_nHoverOption == HOVEROPTION_3 || m_nHoverOption == HOVEROPTION_4 || - m_nHoverOption == HOVEROPTION_5 || m_nHoverOption == HOVEROPTION_6 || m_nHoverOption == HOVEROPTION_7) + menuBg.SaveCurrentCoors(); + switch (m_nCurrScreen) { + case MENUPAGE_STATS: + menuBg.topLeft_x = 70.0f; + menuBg.topLeft_y = 75.0f; + menuBg.topRight_x = 550.0f; + menuBg.topRight_y = 16.0f; + menuBg.bottomLeft_x = 74.0f; + menuBg.bottomLeft_y = 354.0f; + menuBg.bottomRight_x = 581.0f; + menuBg.bottomRight_y = 340.0f; + break; + case MENUPAGE_SOUND_SETTINGS: + menuBg.topLeft_x = 26.0f; + menuBg.topLeft_y = 59.0f; + menuBg.topRight_x = 629.0f; + menuBg.topRight_y = 29.0f; + menuBg.bottomLeft_x = 15.0f; + menuBg.bottomLeft_y = 438.0f; + menuBg.bottomRight_x = 610.0f; + menuBg.bottomRight_y = 410.0f; + break; + case MENUPAGE_SKIN_SELECT: + case MENUPAGE_KEYBOARD_CONTROLS: + menuBg.topLeft_x = 14.0f; + menuBg.topLeft_y = 39.0f; + menuBg.topRight_x = 636.0f; + menuBg.topRight_y = 29.0f; + menuBg.bottomLeft_x = 15.0f; + menuBg.bottomLeft_y = 426.0f; + menuBg.bottomRight_x = 630.0f; + menuBg.bottomRight_y = 398.0f; + break; + case MENUPAGE_BRIEFS: + case MENUPAGE_GRAPHICS_SETTINGS: + case MENUPAGE_MAP: + case MENUPAGE_CHOOSE_LOAD_SLOT: + case MENUPAGE_CHOOSE_DELETE_SLOT: + case MENUPAGE_CHOOSE_SAVE_SLOT: + case MENUPAGE_MOUSE_CONTROLS: + menuBg.topLeft_x = 26.0f; + menuBg.topLeft_y = 59.0f; + menuBg.topRight_x = 629.0f; + menuBg.topRight_y = 29.0f; + menuBg.bottomLeft_x = 15.0f; + menuBg.bottomLeft_y = 426.0f; + menuBg.bottomRight_x = 610.0f; + menuBg.bottomRight_y = 398.0f; + break; + default: + menuBg.topLeft_x = CGeneral::GetRandomNumber() % 40 + 65; + menuBg.topLeft_y = CGeneral::GetRandomNumber() % 40 + 21; + menuBg.topRight_x = CGeneral::GetRandomNumber() % 40 + 568; + menuBg.topRight_y = CGeneral::GetRandomNumber() % 40 + 44; + menuBg.bottomLeft_x = CGeneral::GetRandomNumber() % 40 + 36; + menuBg.bottomLeft_y = CGeneral::GetRandomNumber() % 40 + 382; + menuBg.bottomRight_x = CGeneral::GetRandomNumber() % 40 + 593; + menuBg.bottomRight_y = CGeneral::GetRandomNumber() % 40 + 342; + break; + } - field_518 = 2; - else - field_518 = 1; + menuBg.UpdateMultipliers(); + if (m_menuTransitionProgress == 255) + bOptionHighlightTransitionBlend = 0; + } + + // Congrats R*, instead of solving the bug you just hacked your million dolar product. +#if 0 + + // This is how I fixed it in III, but I can't apply it here because "forceFadeInCounter > 30" gives it a unique effect. + static float fadeAlpha = 0.0f; + if (m_nMenuFadeAlpha == 0 && fadeAlpha > 1.0f) fadeAlpha = 0.0f; + + // +20 per every 33 ms (1000.f/30.f - original frame limiter fps) + fadeAlpha += (frameTime) * 20.f / 33.f; + m_nMenuFadeAlpha = clamp(fadeAlpha, 0, 255); + m_menuTransitionProgress = clamp(fadeAlpha, 0, 255); +#else + static uint32 LastFade = 0; + static uint8 forceFadeInCounter = 0; + + if (m_nMenuFadeAlpha >= 255) { + if (m_nMenuFadeAlpha > 255) + m_nMenuFadeAlpha = 255; + } else { + if (CTimer::GetTimeInMillisecondsPauseMode() - LastFade > 30 || forceFadeInCounter > 30) { + m_nMenuFadeAlpha += 20; + m_menuTransitionProgress = Min(m_menuTransitionProgress + 20, 255); + LastFade = CTimer::GetTimeInMillisecondsPauseMode(); + } + forceFadeInCounter++; + } +#endif + + if (!transitionCall && m_menuTransitionProgress == 255) { + float oldAlpha = m_nMenuFadeAlpha; + if (oldAlpha < 255) { + int oldScreen = m_nCurrScreen; + SetFrontEndRenderStates(); + m_nCurrScreen = m_nPrevScreen; + m_nMenuFadeAlpha = 255 - m_nMenuFadeAlpha; + switch (m_nCurrScreen) { + case MENUPAGE_SKIN_SELECT: + CMenuManager::DrawPlayerSetupScreen(); + break; + case MENUPAGE_KEYBOARD_CONTROLS: + CMenuManager::DrawControllerSetupScreen(); + break; + /* case MENUPAGE_OUTRO: + CMenuManager::DrawQuitGameScreen(); + break; */ // TODO(Miami) + default: + CMenuManager::DrawStandardMenus(); + break; + } + m_nCurrScreen = oldScreen; + m_nMenuFadeAlpha = oldAlpha; } } - // GTA LOGO - RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDSRCALPHA); - RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCALPHA); - if (m_nCurrScreen == MENUPAGE_START_MENU || m_nCurrScreen == MENUPAGE_PAUSE_MENU) { - if (CGame::frenchGame || CGame::germanGame || !CGame::nastyGame) - m_aMenuSprites[MENUSPRITE_GTA3LOGO].Draw(CRect(MENU_X_LEFT_ALIGNED(205.0f), MENU_Y(70.0f), MENU_X_LEFT_ALIGNED(435.0f), MENU_Y(180.0f)), CRGBA(255, 255, 255, FadeIn(255))); - else - m_aMenuSprites[MENUSPRITE_GTALOGO].Draw(CRect(MENU_X_LEFT_ALIGNED(225.0f), MENU_Y(40.0f), MENU_X_LEFT_ALIGNED(415.0f), MENU_Y(210.0f)), CRGBA(255, 255, 255, FadeIn(255))); - } - - RwRenderStateSet(rwRENDERSTATETEXTUREFILTER, (void*)rwFILTERNEAREST); - RwRenderStateSet(rwRENDERSTATETEXTUREADDRESS, (void*)rwTEXTUREADDRESSCLAMP); - RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)FALSE); switch (m_nCurrScreen) { case MENUPAGE_SKIN_SELECT: DrawPlayerSetupScreen(); @@ -2442,35 +2420,33 @@ CMenuManager::DrawFrontEndNormal() case MENUPAGE_KEYBOARD_CONTROLS: DrawControllerSetupScreen(); break; + /* case MENUPAGE_OUTRO: + CMenuManager::DrawQuitGameScreen(); + break; */ // TODO(Miami) default: - Draw(); + DrawStandardMenus(); break; } CFont::DrawFonts(); + SetFrontEndRenderStates(); + +// TODO(Miami) +// if (m_nCurrScreen != MENUPAGE_OUTRO) + if (m_menuTransitionProgress == 255) { + m_aFrontEndSprites[MENUSPRITE_VCLOGO].Draw(CRect(MENU_X(27.0f), MENU_Y(8.0f), MENU_X(157.0f), MENU_Y(138.0f)), CRGBA(255, 255, 255, 255)); + } else { + m_aFrontEndSprites[MENUSPRITE_VCLOGO].Draw(CRect(MENU_X(27.0f), MENU_Y(8.0f), MENU_X(157.0f), MENU_Y(138.0f)), CRGBA(255, 255, 255, FadeIn(255))); + } - // Draw mouse - RwRenderStateSet(rwRENDERSTATETEXTUREFILTER, (void*)rwFILTERLINEAR); - RwRenderStateSet(rwRENDERSTATETEXTUREADDRESS, (void*)rwTEXTUREADDRESSCLAMP); if (m_bShowMouse) { - RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDSRCALPHA); - RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCALPHA); - RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)TRUE); - - CRect mouse(0.0f, 0.0f, MENU_X(75.0f), MENU_Y(75.0f)); - CRect shad(MENU_X(10.0f), MENU_Y(3.0f), MENU_X(85.0f), MENU_Y(78.0f)); + CRect mouse(0.0f, 0.0f, MENU_X(40.0f), MENU_Y(40.0f)); + CRect shad(MENU_X(10.0f), MENU_Y(3.0f), MENU_X(55.0f), MENU_Y(43.0f)); mouse.Translate(m_nMousePosX, m_nMousePosY); shad.Translate(m_nMousePosX, m_nMousePosY); - if(field_518 == 4){ - m_aMenuSprites[MENUSPRITE_MOUSET].Draw(shad, CRGBA(100, 100, 100, 50)); - RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)FALSE); - m_aMenuSprites[MENUSPRITE_MOUSET].Draw(mouse, CRGBA(255, 255, 255, 255)); - }else{ - m_aMenuSprites[MENUSPRITE_MOUSE].Draw(shad, CRGBA(100, 100, 100, 50)); - RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)FALSE); - m_aMenuSprites[MENUSPRITE_MOUSE].Draw(mouse, CRGBA(255, 255, 255, 255)); - } + m_aFrontEndSprites[MENUSPRITE_MOUSE].Draw(shad, CRGBA(100, 100, 100, 50)); + m_aFrontEndSprites[MENUSPRITE_MOUSE].Draw(mouse, CRGBA(255, 255, 255, 255)); } } #endif @@ -2711,21 +2687,21 @@ CMenuManager::DrawPlayerSetupScreen() // 2 - leaves gap between button and scrollbar if (m_nHoverOption == HOVEROPTION_CLICKED_SCROLL_UP) { #ifdef FIX_BUGS - m_aMenuSprites[MENUSPRITE_UPON].Draw(CRect(MENU_X_RIGHT_ALIGNED(PLAYERSETUP_LIST_RIGHT - 2), MENU_Y(PLAYERSETUP_LIST_TOP), + m_aFrontEndSprites[MENUSPRITE_UPON].Draw(CRect(MENU_X_RIGHT_ALIGNED(PLAYERSETUP_LIST_RIGHT - 2), MENU_Y(PLAYERSETUP_LIST_TOP), MENU_X_RIGHT_ALIGNED(PLAYERSETUP_LIST_RIGHT - 2 - PLAYERSETUP_SCROLLBUTTON_TXD_DIMENSION), MENU_Y(PLAYERSETUP_LIST_TOP + PLAYERSETUP_SCROLLBUTTON_TXD_DIMENSION)), CRGBA(255, 255, 255, FadeIn(255))); #else - m_aMenuSprites[MENUSPRITE_UPON].Draw(CRect(MENU_X_RIGHT_ALIGNED(PLAYERSETUP_LIST_RIGHT - 2), MENU_Y(PLAYERSETUP_LIST_TOP), + m_aFrontEndSprites[MENUSPRITE_UPON].Draw(CRect(MENU_X_RIGHT_ALIGNED(PLAYERSETUP_LIST_RIGHT - 2), MENU_Y(PLAYERSETUP_LIST_TOP), MENU_X_RIGHT_ALIGNED(-20.0f), MENU_Y(PLAYERSETUP_LIST_TOP + 58)), CRGBA(255, 255, 255, FadeIn(255))); #endif } else { #ifdef FIX_BUGS - m_aMenuSprites[MENUSPRITE_UPOFF].Draw(CRect(MENU_X_RIGHT_ALIGNED(PLAYERSETUP_LIST_RIGHT - 3), MENU_Y(PLAYERSETUP_LIST_TOP), + m_aFrontEndSprites[MENUSPRITE_UPOFF].Draw(CRect(MENU_X_RIGHT_ALIGNED(PLAYERSETUP_LIST_RIGHT - 3), MENU_Y(PLAYERSETUP_LIST_TOP), MENU_X_RIGHT_ALIGNED(PLAYERSETUP_LIST_RIGHT - 3 - PLAYERSETUP_SCROLLBUTTON_TXD_DIMENSION), MENU_Y(PLAYERSETUP_LIST_TOP + PLAYERSETUP_SCROLLBUTTON_TXD_DIMENSION)), CRGBA(255, 255, 255, FadeIn(255))); #else - m_aMenuSprites[MENUSPRITE_UPOFF].Draw(CRect(MENU_X_RIGHT_ALIGNED(PLAYERSETUP_LIST_RIGHT - 3), MENU_Y(PLAYERSETUP_LIST_TOP), + m_aFrontEndSprites[MENUSPRITE_UPOFF].Draw(CRect(MENU_X_RIGHT_ALIGNED(PLAYERSETUP_LIST_RIGHT - 3), MENU_Y(PLAYERSETUP_LIST_TOP), MENU_X_RIGHT_ALIGNED(-21.0f), MENU_Y(PLAYERSETUP_LIST_TOP + 58)), CRGBA(255, 255, 255, FadeIn(255))); #endif @@ -2733,21 +2709,21 @@ CMenuManager::DrawPlayerSetupScreen() if (m_nHoverOption == HOVEROPTION_CLICKED_SCROLL_DOWN) { #ifdef FIX_BUGS - m_aMenuSprites[MENUSPRITE_DOWNON].Draw(CRect(MENU_X_RIGHT_ALIGNED(PLAYERSETUP_LIST_RIGHT - 2), SCREEN_SCALE_FROM_BOTTOM(PLAYERSETUP_LIST_BOTTOM + PLAYERSETUP_SCROLLBUTTON_HEIGHT + 1), + m_aFrontEndSprites[MENUSPRITE_DOWNON].Draw(CRect(MENU_X_RIGHT_ALIGNED(PLAYERSETUP_LIST_RIGHT - 2), SCREEN_SCALE_FROM_BOTTOM(PLAYERSETUP_LIST_BOTTOM + PLAYERSETUP_SCROLLBUTTON_HEIGHT + 1), MENU_X_RIGHT_ALIGNED(PLAYERSETUP_LIST_RIGHT - 2 - PLAYERSETUP_SCROLLBUTTON_TXD_DIMENSION), SCREEN_SCALE_FROM_BOTTOM(PLAYERSETUP_LIST_BOTTOM + PLAYERSETUP_SCROLLBUTTON_HEIGHT + 1 - PLAYERSETUP_SCROLLBUTTON_TXD_DIMENSION)), CRGBA(255, 255, 255, FadeIn(255))); #else - m_aMenuSprites[MENUSPRITE_DOWNON].Draw(CRect(MENU_X_RIGHT_ALIGNED(PLAYERSETUP_LIST_RIGHT - 2), SCREEN_SCALE_FROM_BOTTOM(141.0f), + m_aFrontEndSprites[MENUSPRITE_DOWNON].Draw(CRect(MENU_X_RIGHT_ALIGNED(PLAYERSETUP_LIST_RIGHT - 2), SCREEN_SCALE_FROM_BOTTOM(141.0f), MENU_X_RIGHT_ALIGNED(-20.0f), SCREEN_SCALE_FROM_BOTTOM(83.0f)), CRGBA(255, 255, 255, FadeIn(255))); #endif } else { #ifdef FIX_BUGS - m_aMenuSprites[MENUSPRITE_DOWNOFF].Draw(CRect(MENU_X_RIGHT_ALIGNED(PLAYERSETUP_LIST_RIGHT - 3), SCREEN_SCALE_FROM_BOTTOM(PLAYERSETUP_LIST_BOTTOM + PLAYERSETUP_SCROLLBUTTON_HEIGHT + 1), + m_aFrontEndSprites[MENUSPRITE_DOWNOFF].Draw(CRect(MENU_X_RIGHT_ALIGNED(PLAYERSETUP_LIST_RIGHT - 3), SCREEN_SCALE_FROM_BOTTOM(PLAYERSETUP_LIST_BOTTOM + PLAYERSETUP_SCROLLBUTTON_HEIGHT + 1), MENU_X_RIGHT_ALIGNED(PLAYERSETUP_LIST_RIGHT - 3 - PLAYERSETUP_SCROLLBUTTON_TXD_DIMENSION), SCREEN_SCALE_FROM_BOTTOM(PLAYERSETUP_LIST_BOTTOM + PLAYERSETUP_SCROLLBUTTON_HEIGHT + 1 - PLAYERSETUP_SCROLLBUTTON_TXD_DIMENSION)), CRGBA(255, 255, 255, FadeIn(255))); #else - m_aMenuSprites[MENUSPRITE_DOWNOFF].Draw(CRect(MENU_X_RIGHT_ALIGNED(PLAYERSETUP_LIST_RIGHT - 3), SCREEN_SCALE_FROM_BOTTOM(141.0f), + m_aFrontEndSprites[MENUSPRITE_DOWNOFF].Draw(CRect(MENU_X_RIGHT_ALIGNED(PLAYERSETUP_LIST_RIGHT - 3), SCREEN_SCALE_FROM_BOTTOM(141.0f), MENU_X_RIGHT_ALIGNED(-21.0f), SCREEN_SCALE_FROM_BOTTOM(83.0f)), CRGBA(255, 255, 255, FadeIn(255))); #endif @@ -2889,11 +2865,6 @@ CMenuManager::DrawPlayerSetupScreen() int CMenuManager::FadeIn(int alpha) { - if (m_nCurrScreen == MENUPAGE_LOADING_IN_PROGRESS || - m_nCurrScreen == MENUPAGE_SAVING_IN_PROGRESS || - m_nCurrScreen == MENUPAGE_DELETING) - return alpha; - return Min(m_nMenuFadeAlpha, alpha); } @@ -3002,70 +2973,57 @@ CMenuManager::LoadAllTextures() if (m_bSpritesLoaded) return; - CentreMousePointer(); - DMAudio.ChangeMusicMode(MUSICMODE_FRONTEND); - DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_STARTING, 0); - m_nCurrOption = 0; - m_PrefsRadioStation = DMAudio.GetRadioInCar(); - - if (DMAudio.IsMP3RadioChannelAvailable()) { - if (m_PrefsRadioStation > USERTRACK) - m_PrefsRadioStation = CGeneral::GetRandomNumber() % 10; - } else if (m_PrefsRadioStation > CHATTERBOX) - m_PrefsRadioStation = CGeneral::GetRandomNumber() % 9; - - CFileMgr::SetDir(""); - //CFileMgr::SetDir(""); + field_F0 = SCREEN_STRETCH_X(178.0f); // TODO(Miami) CTimer::Stop(); + CStreaming::MakeSpaceFor(350 * CDSTREAM_SECTOR_SIZE); // twice of it in mobile CStreaming::ImGonnaUseStreamingMemory(); CGame::TidyUpMemory(false, true); CTxdStore::PushCurrentTxd(); - int frontendTxdSlot = CTxdStore::FindTxdSlot("frontend"); + int frontendTxdSlot1 = CTxdStore::FindTxdSlot("frontend1"); - if(frontendTxdSlot == -1) - frontendTxdSlot = CTxdStore::AddTxdSlot("frontend"); + if(frontendTxdSlot1 == -1) + frontendTxdSlot1 = CTxdStore::AddTxdSlot("frontend1"); - printf("LOAD frontend\n"); - CTxdStore::LoadTxd(frontendTxdSlot, "MODELS/FRONTEND.TXD"); - CTxdStore::AddRef(frontendTxdSlot); - CTxdStore::SetCurrentTxd(frontendTxdSlot); -#ifndef GTA3_1_1_PATCH - CStreaming::IHaveUsedStreamingMemory(); - CTimer::Update(); -#endif + printf("LOAD frontend1\n"); + CTxdStore::LoadTxd(frontendTxdSlot1, "MODELS/FRONTEN1.TXD"); + CTxdStore::AddRef(frontendTxdSlot1); + CTxdStore::SetCurrentTxd(frontendTxdSlot1); - for (int i = 0; i < ARRAY_SIZE(FrontendFilenames); i++) { + for (int i = 0; i < 3; i++) { m_aFrontEndSprites[i].SetTexture(FrontendFilenames[i][0], FrontendFilenames[i][1]); m_aFrontEndSprites[i].SetAddressing(rwTEXTUREADDRESSBORDER); } - int menuTxdSlot = CTxdStore::FindTxdSlot("menu"); - - if (menuTxdSlot == -1) - menuTxdSlot = CTxdStore::AddTxdSlot("menu"); - - printf("LOAD sprite\n"); - CTxdStore::LoadTxd(menuTxdSlot, "MODELS/MENU.TXD"); - CTxdStore::AddRef(menuTxdSlot); - CTxdStore::SetCurrentTxd(menuTxdSlot); - - for (int i = 0; i < ARRAY_SIZE(MenuFilenames); i++) { - m_aMenuSprites[i].SetTexture(MenuFilenames[i][0], MenuFilenames[i][1]); - m_aMenuSprites[i].SetAddressing(rwTEXTUREADDRESSBORDER); - } -#ifdef MENU_MAP - for (int i = 0; i < ARRAY_SIZE(MapFilenames); i++) { - m_aMapSprites[i].SetTexture(MapFilenames[i][0], MapFilenames[i][1]); - m_aMapSprites[i].SetAddressing(rwTEXTUREADDRESSBORDER); - } -#endif -#ifdef GTA3_1_1_PATCH - CStreaming::IHaveUsedStreamingMemory(); - CTimer::Update(); -#endif - m_bSpritesLoaded = true; CTxdStore::PopCurrentTxd(); + CStreaming::IHaveUsedStreamingMemory(); + + if (!m_OnlySaveMenu) { + CStreaming::MakeSpaceFor(692 * CDSTREAM_SECTOR_SIZE); // twice of it in mobile + CStreaming::ImGonnaUseStreamingMemory(); + CTxdStore::PushCurrentTxd(); + + int frontendTxdSlot2 = CTxdStore::FindTxdSlot("frontend2"); + + if (frontendTxdSlot2 == -1) + frontendTxdSlot2 = CTxdStore::AddTxdSlot("frontend2"); + + printf("LOAD frontend2\n"); + CTxdStore::LoadTxd(frontendTxdSlot2, "MODELS/FRONTEN2.TXD"); + CTxdStore::AddRef(frontendTxdSlot2); + CTxdStore::SetCurrentTxd(frontendTxdSlot2); + + for (int i = 3; i < NUM_MENU_SPRITES; i++) { + m_aFrontEndSprites[i].SetTexture(FrontendFilenames[i][0], FrontendFilenames[i][1]); + m_aFrontEndSprites[i].SetAddressing(rwTEXTUREADDRESSBORDER); + } + + CTxdStore::PopCurrentTxd(); + CStreaming::IHaveUsedStreamingMemory(); + } + + m_bSpritesLoaded = true; + CTimer::Update(); } void @@ -3138,6 +3096,9 @@ CMenuManager::LoadSettings() CFileMgr::Read(fileHandle, m_PrefsSkinFile, 256); CFileMgr::Read(fileHandle, (char*)&m_ControlMethod, 1); CFileMgr::Read(fileHandle, (char*)&m_PrefsLanguage, 1); +#ifdef FREE_CAM + CFileMgr::Read(fileHandle, (char*)&TheCamera.bFreeCam, 1); +#endif } } @@ -3147,9 +3108,11 @@ CMenuManager::LoadSettings() m_PrefsVsync = m_PrefsVsyncDisp; CRenderer::ms_lodDistScale = m_PrefsLOD; - if (m_nPrefsAudio3DProviderIndex == -1) + if (m_nPrefsAudio3DProviderIndex == INVALID_AUDIO_PROVIDER) m_nPrefsAudio3DProviderIndex = -2; + m_lastWorking3DAudioProvider = m_nPrefsAudio3DProviderIndex; + if (m_PrefsLanguage == prevLang) m_bLanguageLoaded = false; else { @@ -3228,15 +3191,16 @@ CMenuManager::SaveSettings() CFileMgr::Write(fileHandle, m_PrefsSkinFile, 256); CFileMgr::Write(fileHandle, (char*)&m_ControlMethod, 1); CFileMgr::Write(fileHandle, (char*)&m_PrefsLanguage, 1); +#ifdef FREE_CAM + CFileMgr::Write(fileHandle, (char*)&TheCamera.bFreeCam, 1); +#endif } + m_lastWorking3DAudioProvider = m_nPrefsAudio3DProviderIndex; CFileMgr::CloseFile(fileHandle); CFileMgr::SetDir(""); } -bool DoRWStuffStartOfFrame(int16 TopRed, int16 TopGreen, int16 TopBlue, int16 BottomRed, int16 BottomGreen, int16 BottomBlue, int16 Alpha); -void DoRWStuffEndOfFrame(void); - void CMenuManager::MessageScreen(const char *text) { @@ -3269,22 +3233,6 @@ CMenuManager::MessageScreen(const char *text) DoRWStuffEndOfFrame(); } -void -CMenuManager::PickNewPlayerColour() -{ - m_PrefsPlayerRed = 0; - m_PrefsPlayerGreen = 0; - m_PrefsPlayerBlue = 0; - while (true) { - int sum = m_PrefsPlayerRed + m_PrefsPlayerGreen + m_PrefsPlayerBlue; - if (sum >= 100 && sum <= 650) - break; - m_PrefsPlayerRed = CGeneral::GetRandomNumber(); - m_PrefsPlayerGreen = CGeneral::GetRandomNumber(); - m_PrefsPlayerBlue = CGeneral::GetRandomNumber(); - } -} - void CMenuManager::PrintBriefs() { @@ -3336,30 +3284,6 @@ CMenuManager::PrintBriefs() #endif } -// Not sure about name. Not to be confused with CPad::PrintErrorMessage -void -CMenuManager::PrintErrorMessage() -{ - if (!CPad::bDisplayNoControllerMessage && !CPad::bObsoleteControllerMessage) - return; - - CSprite2d::DrawRect(CRect(SCREEN_SCALE_X(20.0f), SCREEN_SCALE_Y(140.0f), SCREEN_SCALE_FROM_RIGHT(20.0f), SCREEN_SCALE_FROM_BOTTOM(120.0f)), CRGBA(64, 16, 16, 224)); - CFont::SetFontStyle(FONT_LOCALE(FONT_BANK)); - CFont::SetBackgroundOff(); - CFont::SetPropOn(); - CFont::SetCentreOff(); - CFont::SetJustifyOn(); - CFont::SetRightJustifyOff(); - CFont::SetBackGroundOnlyTextOn(); - CFont::SetWrapx(SCREEN_SCALE_FROM_RIGHT(40.0f)); -#ifdef FIX_BUGS - CFont::PrintString(SCREEN_SCALE_X(50.0f), SCREEN_SCALE_Y(180.0f), TheText.Get(CPad::bDisplayNoControllerMessage ? "NOCONT" : "WRCONT")); -#else - CFont::PrintString(SCREEN_SCALE_X(50.0f), SCREEN_SCALE_Y(40.0f), TheText.Get(CPad::bDisplayNoControllerMessage ? "NOCONT" : "WRCONT")); -#endif - CFont::DrawFonts(); -} - void CMenuManager::PrintStats() { @@ -3373,7 +3297,7 @@ CMenuManager::PrintStats() // Scroll stats with mouse #ifdef SCROLLABLE_STATS_PAGE static float scrollY = 0; - static uint32 lastChange = m_nScreenChangeDelayTimer; + static uint32 lastChange = m_LastScreenSwitch; if (CPad::GetPad(0)->GetLeftMouse()) { scrollY += (m_nMouseOldPosY - m_nMousePosY); lastChange = CTimer::GetTimeInMillisecondsPauseMode(); @@ -3383,7 +3307,7 @@ CMenuManager::PrintStats() } #else // MENU_Y(30.0f) per second - float scrollY = MENU_Y(STATS_SLIDE_Y_PER_SECOND) * (CTimer::GetTimeInMillisecondsPauseMode() - m_nScreenChangeDelayTimer) / 1000.0f; + float scrollY = MENU_Y(STATS_SLIDE_Y_PER_SECOND) * (CTimer::GetTimeInMillisecondsPauseMode() - m_LastScreenSwitch) / 1000.0f; #endif for (int row = 0; row < rowNum; ++row) { @@ -3446,167 +3370,95 @@ CMenuManager::PrintStats() // ::Draw already does that. /* PREPARE_MENU_HEADER - CFont::PrintString(MENU_X_RIGHT_ALIGNED(MENUHEADER_POS_X), SCREEN_SCALE_FROM_BOTTOM(MENUHEADER_POS_Y), TheText.Get(aScreens[m_nCurrScreen].m_ScreenName)); + CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(MENUHEADER_POS_X), SCREEN_SCALE_FROM_BOTTOM(MENUHEADER_POS_Y), TheText.Get(aScreens[m_nCurrScreen].m_ScreenName)); */ CFont::SetScale(MENU_X(MENU_TEXT_SIZE_X), MENU_Y(MENU_TEXT_SIZE_Y)); } +// --MIAMI: Done void CMenuManager::Process(void) { - m_bMenuStateChanged = false; - - if (!m_bSaveMenuActive && TheCamera.GetScreenFadeStatus() != FADE_0) + if (TheCamera.GetScreenFadeStatus() != FADE_0) return; - m_bWantToRestart = false; InitialiseChangedLanguageSettings(); - // Just a hack by R* to not make game continuously resume/pause. But we it seems we can live with it. - if (CPad::GetPad(0)->GetEscapeJustDown()) - RequestFrontEndStartUp(); + if (m_bMenuActive) { + ProcessButtonPresses(); + ProcessFileActions(); + DMAudio.Service(); + + // Game calls some texture pool cleanup functions in here + } SwitchMenuOnAndOff(); - - // Be able to re-open menu correctly. - if (m_bMenuActive) { - - // Load frontend textures. - LoadAllTextures(); - - // Set save/delete game pages. - if (m_nCurrScreen == MENUPAGE_DELETING) { - bool SlotPopulated = false; - - if (PcSaveHelper.DeleteSlot(m_nCurrSaveSlot)) { - PcSaveHelper.PopulateSlotInfo(); - SlotPopulated = true; - } - - if (SlotPopulated) - ChangeScreen(MENUPAGE_DELETE_SUCCESS, 0, true, false); - else - SaveLoadFileError_SetUpErrorScreen(); - } - if (m_nCurrScreen == MENUPAGE_SAVING_IN_PROGRESS) { - int8 SaveSlot = PcSaveHelper.SaveSlot(m_nCurrSaveSlot); - PcSaveHelper.PopulateSlotInfo(); - if (SaveSlot) - ChangeScreen(MENUPAGE_SAVE_SUCCESSFUL, 0, true, false); - else - SaveLoadFileError_SetUpErrorScreen(); - } - if (m_nCurrScreen == MENUPAGE_LOADING_IN_PROGRESS) { - if (CheckSlotDataValid(m_nCurrSaveSlot)) { - TheCamera.m_bUseMouse3rdPerson = m_ControlMethod == CONTROL_STANDARD; - if (m_PrefsVsyncDisp != m_PrefsVsync) - m_PrefsVsync = m_PrefsVsyncDisp; - DMAudio.Service(); - m_bWantToRestart = true; - RequestFrontEndShutDown(); - m_bWantToLoad = true; - b_FoundRecentSavedGameWantToLoad = true; - DMAudio.SetEffectsFadeVol(0); - DMAudio.SetMusicFadeVol(0); - DMAudio.ResetTimers(CTimer::GetTimeInMilliseconds()); - } else - SaveLoadFileError_SetUpErrorScreen(); - } - - ProcessButtonPresses(); - - // Set binding keys. - if (pEditString && CPad::EditString(pEditString, 0) == nil) { - if (*pEditString == 0) - strcpy(pEditString, "NoName"); - pEditString = nil; - SaveSettings(); - } - - if (m_bWaitingForNewKeyBind) { - if (m_bStartWaitingForKeyBind) - m_bStartWaitingForKeyBind = false; - else { - pControlEdit = CPad::EditCodesForControls(pControlEdit, 1); - JoyButtonJustClicked = false; - MouseButtonJustClicked = false; - - if (CPad::GetPad(0)->GetLeftMouseJustDown()) - MouseButtonJustClicked = 1; - else if (CPad::GetPad(0)->GetRightMouseJustUp()) - MouseButtonJustClicked = 3; - else if (CPad::GetPad(0)->GetMiddleMouseJustUp()) - MouseButtonJustClicked = 2; - else if (CPad::GetPad(0)->GetMouseWheelUpJustUp()) - MouseButtonJustClicked = 4; - else if (CPad::GetPad(0)->GetMouseWheelDownJustUp()) - MouseButtonJustClicked = 5; - // TODO two more buttons - - JoyButtonJustClicked = ControlsManager.GetJoyButtonJustDown(); - - int32 TypeOfControl = KEYBOARD; - if (JoyButtonJustClicked) - TypeOfControl = JOYSTICK; - if (MouseButtonJustClicked) - TypeOfControl = MOUSE; - if (*pControlEdit != rsNULL) - TypeOfControl = KEYBOARD; - - if (!m_bKeyIsOK) { - DMAudio.PlayFrontEndSound(SOUND_FRONTEND_FAIL, 0); - pControlEdit = nil; - m_bWaitingForNewKeyBind = false; - m_KeyPressedCode = -1; - m_bStartWaitingForKeyBind = false; - } else if (!m_bKeyChangeNotProcessed) { - if (*pControlEdit != rsNULL || MouseButtonJustClicked || JoyButtonJustClicked) - CheckCodesForControls(TypeOfControl); - - field_535 = true; - } else { - DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SUCCESS, 0); - for (int i = 0; i < 4; i++) - ControlsManager.ClearSettingsAssociatedWithAction((e_ControllerAction)m_CurrCntrlAction, (eControllerType)i); - m_bKeyIsOK = false; - m_bKeyChangeNotProcessed = false; - pControlEdit = nil; - m_bWaitingForNewKeyBind = false; - m_KeyPressedCode = -1; - m_bStartWaitingForKeyBind = false; - } - } - } - - if ((m_nCurrScreen == MENUPAGE_NO_MEMORY_CARD || m_nCurrScreen == MENUPAGE_PS2_LOAD_FAILED) && CTimer::GetTimeInMillisecondsPauseMode() > field_558) { - m_nCurrScreen = m_nPrevScreen; - m_nCurrOption = 0; - } - - // Reset pad shaking. - if (TimeToStopPadShaking && TimeToStopPadShaking < CTimer::GetTimeInMillisecondsPauseMode()) { - CPad::StopPadsShaking(); - TimeToStopPadShaking = 0; - } - - } else { - UnloadTextures(); - m_bRenderGameInMenu = false; - // byte_5F33E4 = 1; // unused - ChangeScreen(MENUPAGE_NONE, 0, false, false); - pEditString = nil; - m_bWaitingForNewKeyBind = false; - } - - if (!m_bWantToRestart) { - if (m_bGameNotLoaded) - DMAudio.Service(); - } } void CMenuManager::ProcessButtonPresses(void) { + // TODO(Miami) + // if (m_nCurrScreen == MENUPAGE_OUTRO) + // return; + + if (m_bWaitingForNewKeyBind) { + if (m_bStartWaitingForKeyBind) + m_bStartWaitingForKeyBind = false; + else { + pControlEdit = CPad::EditCodesForControls(pControlEdit, 1); + JoyButtonJustClicked = false; + MouseButtonJustClicked = false; + + if (CPad::GetPad(0)->GetLeftMouseJustDown()) + MouseButtonJustClicked = 1; + else if (CPad::GetPad(0)->GetRightMouseJustUp()) + MouseButtonJustClicked = 3; + else if (CPad::GetPad(0)->GetMiddleMouseJustUp()) + MouseButtonJustClicked = 2; + else if (CPad::GetPad(0)->GetMouseWheelUpJustUp()) + MouseButtonJustClicked = 4; + else if (CPad::GetPad(0)->GetMouseWheelDownJustUp()) + MouseButtonJustClicked = 5; + // TODO two more buttons + + JoyButtonJustClicked = ControlsManager.GetJoyButtonJustDown(); + + int32 TypeOfControl = KEYBOARD; + if (JoyButtonJustClicked) + TypeOfControl = JOYSTICK; + if (MouseButtonJustClicked) + TypeOfControl = MOUSE; + if (*pControlEdit != rsNULL) + TypeOfControl = KEYBOARD; + + if (!m_bKeyIsOK) { + DMAudio.PlayFrontEndSound(SOUND_FRONTEND_FAIL, 0); + pControlEdit = nil; + m_bWaitingForNewKeyBind = false; + m_KeyPressedCode = -1; + m_bStartWaitingForKeyBind = false; + } + else if (!m_bKeyChangeNotProcessed) { + if (*pControlEdit != rsNULL || MouseButtonJustClicked || JoyButtonJustClicked) + CheckCodesForControls(TypeOfControl); + + field_159 = true; + } + else { + DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SUCCESS, 0); + for (int i = 0; i < 4; i++) + ControlsManager.ClearSettingsAssociatedWithAction((e_ControllerAction)m_CurrCntrlAction, (eControllerType)i); + m_bKeyIsOK = false; + m_bKeyChangeNotProcessed = false; + pControlEdit = nil; + m_bWaitingForNewKeyBind = false; + m_KeyPressedCode = -1; + m_bStartWaitingForKeyBind = false; + } + } + } + if (pEditString || pControlEdit) return; @@ -3650,7 +3502,7 @@ CMenuManager::ProcessButtonPresses(void) optionSelected = true; } #endif - if (CPad::GetPad(0)->GetBackspaceJustDown() && m_nCurrScreen == MENUPAGE_KEYBOARD_CONTROLS && !field_535) { + if (CPad::GetPad(0)->GetBackspaceJustDown() && m_nCurrScreen == MENUPAGE_KEYBOARD_CONTROLS && !field_159) { if (m_nCurrExLayer == HOVEROPTION_LIST) { m_nHoverOption = HOVEROPTION_NOT_HOVERING; m_bWaitingForNewKeyBind = true; @@ -3659,7 +3511,7 @@ CMenuManager::ProcessButtonPresses(void) pControlEdit = &m_KeyPressedCode; } } else { - field_535 = false; + field_159 = false; } static uint32 lastTimeClickedScrollButton = 0; @@ -4322,10 +4174,7 @@ CMenuManager::ProcessButtonPresses(void) CWorld::Players[0].SetPlayerSkin(m_PrefsSkinFile); SaveSettings(); } else { - if (!m_bGameNotLoaded) - ChangeScreen(aScreens[m_nCurrScreen].m_PreviousPage[1], aScreens[m_nCurrScreen].m_ParentEntry[1], true, true); - else - ChangeScreen(aScreens[m_nCurrScreen].m_PreviousPage[0], aScreens[m_nCurrScreen].m_ParentEntry[0], true, true); + SwitchToNewScreen(-2); } } else if (m_nCurrScreen != MENUPAGE_MULTIPLAYER_FIND_GAME) { option = aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_Action; @@ -4425,11 +4274,7 @@ CMenuManager::ProcessButtonPresses(void) if (changeMenu) { if (strncmp(aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_EntryName, "FEDS_TB", 8) == 0) { #ifndef TIDY_UP_PBP - ResetHelperText(); - if (!m_bGameNotLoaded) - ChangeScreen(aScreens[m_nCurrScreen].m_PreviousPage[1], aScreens[m_nCurrScreen].m_ParentEntry[1], true, true); - else - ChangeScreen(aScreens[m_nCurrScreen].m_PreviousPage[0], aScreens[m_nCurrScreen].m_ParentEntry[0], true, true); + RequestFrontEndShutDown(); #else goBack = true; break; @@ -4441,7 +4286,7 @@ CMenuManager::ProcessButtonPresses(void) } #endif - ChangeScreen(aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_TargetMenu, 0, true, true); + SwitchToNewScreen(0); } } break; @@ -4453,7 +4298,7 @@ CMenuManager::ProcessButtonPresses(void) if (saveSlot >= 2 && saveSlot <= 9) { m_nCurrSaveSlot = saveSlot - 2; if (Slots[m_nCurrSaveSlot + 1] != SLOT_EMPTY && Slots[m_nCurrSaveSlot + 1] != SLOT_CORRUPTED) { - ChangeScreen(aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_TargetMenu, 0, true, true); + SwitchToNewScreen(0); } } break; @@ -4475,32 +4320,8 @@ CMenuManager::ProcessButtonPresses(void) case MENUACTION_RESUME_FROM_SAVEZONE: RequestFrontEndShutDown(); break; - case MENUACTION_MPMAP_LIBERTY: - case MENUACTION_MPMAP_REDLIGHT: - case MENUACTION_MPMAP_CHINATOWN: - case MENUACTION_MPMAP_TOWER: - case MENUACTION_MPMAP_SEWER: - case MENUACTION_MPMAP_INDUSTPARK: - case MENUACTION_MPMAP_DOCKS: - case MENUACTION_MPMAP_STAUNTON: - m_SelectedMap = option - MENUACTION_MPMAP_LIBERTY; - SaveSettings(); - ChangeScreen(aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_TargetMenu, 0, true, true); - break; - case MENUACTION_MPMAP_DEATHMATCH1: - case MENUACTION_MPMAP_DEATHMATCH2: - case MENUACTION_MPMAP_TEAMDEATH1: - case MENUACTION_MPMAP_TEAMDEATH2: - case MENUACTION_MPMAP_STASH: - case MENUACTION_MPMAP_CAPTURE: - case MENUACTION_MPMAP_RATRACE: - case MENUACTION_MPMAP_DOMINATION: - m_SelectedGameType = option - MENUACTION_MPMAP_DEATHMATCH1; - SaveSettings(); - ChangeScreen(aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_TargetMenu, 0, true, true); - break; case MENUACTION_REDEFCTRL: - ChangeScreen(MENUPAGE_KEYBOARD_CONTROLS, 0, true, true); + SwitchToNewScreen(MENUPAGE_KEYBOARD_CONTROLS); m_nSelectedListRow = 0; m_nCurrExLayer = HOVEROPTION_LIST; break; @@ -4526,13 +4347,19 @@ CMenuManager::ProcessButtonPresses(void) #endif break; case MENUACTION_DONTCANCEL: - ChangeScreen(aScreens[m_nCurrScreen].m_PreviousPage[1], aScreens[m_nCurrScreen].m_ParentEntry[1], true, true); + SwitchToNewScreen(-2); break; case MENUACTION_SCREENRES: if (m_nDisplayVideoMode != m_nPrefsVideoMode) { m_nPrefsVideoMode = m_nDisplayVideoMode; _psSelectScreenVM(m_nPrefsVideoMode); - SetHelperText(0); + SetHelperText(0); // TODO(Miami): Remove that + DMAudio.ChangeMusicMode(MUSICMODE_FRONTEND); + DMAudio.Service(); + CentreMousePointer(); + m_bShowMouse = true; + // m_nCurrOption = 5; // Why? + bOptionHighlightTransitionBlend = 0; SaveSettings(); } break; @@ -4549,7 +4376,7 @@ CMenuManager::ProcessButtonPresses(void) case MENUACTION_AUDIOHW: { int selectedProvider = m_nPrefsAudio3DProviderIndex; - if (selectedProvider != -1) { + if (selectedProvider != INVALID_AUDIO_PROVIDER) { m_nPrefsAudio3DProviderIndex = DMAudio.SetCurrent3DProvider(m_nPrefsAudio3DProviderIndex); if (selectedProvider == m_nPrefsAudio3DProviderIndex) { DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SUCCESS, 0); @@ -4564,7 +4391,7 @@ CMenuManager::ProcessButtonPresses(void) } case MENUACTION_SPEAKERCONF: #ifndef TIDY_UP_PBP - if (m_nPrefsAudio3DProviderIndex != -1) { + if (m_nPrefsAudio3DProviderIndex != INVALID_AUDIO_PROVIDER) { if (--m_PrefsSpeakers < 0) m_PrefsSpeakers = 2; DMAudio.SetSpeakerConfig(m_PrefsSpeakers); @@ -4576,7 +4403,7 @@ CMenuManager::ProcessButtonPresses(void) break; case MENUACTION_PLAYERSETUP: CPlayerSkin::BeginFrontendSkinEdit(); - ChangeScreen(MENUPAGE_SKIN_SELECT, 0, true, true); + SwitchToNewScreen(MENUPAGE_SKIN_SELECT); m_nCurrExLayer = HOVEROPTION_LIST; m_bSkinsEnumerated = false; break; @@ -4657,7 +4484,7 @@ CMenuManager::ProcessButtonPresses(void) #endif break; case MENUACTION_LOADRADIO: - ChangeScreen(MENUPAGE_SOUND_SETTINGS, 0, true, true); + SwitchToNewScreen(MENUPAGE_SOUND_SETTINGS); DMAudio.PlayFrontEndTrack(m_PrefsRadioStation, 1); OutputDebugString("STARTED PLAYING FRONTEND AUDIO TRACK"); break; @@ -4674,7 +4501,7 @@ CMenuManager::ProcessButtonPresses(void) #else if (m_nCurrScreen == MENUPAGE_PAUSE_MENU) { #endif - if (!m_bGameNotLoaded && !m_bMenuStateChanged) { + if (!m_bGameNotLoaded) { if (m_PrefsVsyncDisp != m_PrefsVsync) { m_PrefsVsync = m_PrefsVsyncDisp; } @@ -4702,7 +4529,6 @@ CMenuManager::ProcessButtonPresses(void) #endif int oldScreen = !m_bGameNotLoaded ? aScreens[m_nCurrScreen].m_PreviousPage[1] : aScreens[m_nCurrScreen].m_PreviousPage[0]; - int oldOption = !m_bGameNotLoaded ? aScreens[m_nCurrScreen].m_ParentEntry[1] : aScreens[m_nCurrScreen].m_ParentEntry[0]; if (oldScreen != -1) { ThingsToDoBeforeLeavingPage(); @@ -4714,7 +4540,7 @@ CMenuManager::ProcessButtonPresses(void) } else #endif { - ChangeScreen(oldScreen, oldOption, true, true); + SwitchToNewScreen(-2); } // We will go back for sure at this point, why process other things?! @@ -4841,14 +4667,14 @@ CMenuManager::ProcessButtonPresses(void) break; #endif case MENUACTION_AUDIOHW: - if (m_nPrefsAudio3DProviderIndex != -1) { + if (m_nPrefsAudio3DProviderIndex != INVALID_AUDIO_PROVIDER) { m_nPrefsAudio3DProviderIndex += changeValueBy; m_nPrefsAudio3DProviderIndex = clamp(m_nPrefsAudio3DProviderIndex, 0, DMAudio.GetNum3DProvidersAvailable() - 1); } DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_DENIED, 0); break; case MENUACTION_SPEAKERCONF: - if (m_nPrefsAudio3DProviderIndex != -1) { + if (m_nPrefsAudio3DProviderIndex != INVALID_AUDIO_PROVIDER) { m_PrefsSpeakers -= changeValueBy; m_PrefsSpeakers = clamp(m_PrefsSpeakers, 0, 2); DMAudio.SetSpeakerConfig(m_PrefsSpeakers); @@ -4881,11 +4707,6 @@ CMenuManager::ProcessOnOffMenuOptions() switch (aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_Action) { case MENUACTION_CTRLVIBRATION: m_PrefsUseVibration = !m_PrefsUseVibration; - - if (m_PrefsUseVibration) { - CPad::GetPad(0)->StartShake(350, 150); - TimeToStopPadShaking = CTimer::GetTimeInMillisecondsPauseMode() + 500; - } DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SUCCESS, 0); break; case MENUACTION_CTRLCONFIG: @@ -4894,10 +4715,6 @@ CMenuManager::ProcessOnOffMenuOptions() CPad::GetPad(0)->Mode = 0; DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SUCCESS, 0); break; - case MENUACTION_CTRLDISPLAY: - m_DisplayControllerOnFoot = !m_DisplayControllerOnFoot; - DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SUCCESS, 0); - break; case MENUACTION_FRAMESYNC: m_PrefsVsyncDisp = !m_PrefsVsyncDisp; DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SUCCESS, 0); @@ -4949,11 +4766,6 @@ CMenuManager::ProcessOnOffMenuOptions() gbShowCollisionPolys = !gbShowCollisionPolys; DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SUCCESS, 0); break; - case MENUACTION_MP_PLAYERCOLOR: - PickNewPlayerColour(); - DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SUCCESS, 0); - SaveSettings(); - break; case MENUACTION_SHOWHEADBOB: TheCamera.m_bHeadBob = !TheCamera.m_bHeadBob; DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SUCCESS, 0); @@ -4975,6 +4787,13 @@ CMenuManager::ProcessOnOffMenuOptions() DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SUCCESS, 0); SaveSettings(); break; +#ifdef FREE_CAM + case MENUACTION_FREECAM: + TheCamera.bFreeCam = !TheCamera.bFreeCam; + DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SUCCESS, 0); + SaveSettings(); + break; +#endif } } @@ -4982,7 +4801,6 @@ void CMenuManager::RequestFrontEndShutDown() { m_bShutDownFrontEndRequested = true; - DMAudio.ChangeMusicMode(MUSICMODE_GAME); } void @@ -5005,20 +4823,20 @@ CMenuManager::SaveLoadFileError_SetUpErrorScreen() case SAVESTATUS_ERR_SAVE_CREATE: case SAVESTATUS_ERR_SAVE_WRITE: case SAVESTATUS_ERR_SAVE_CLOSE: - ChangeScreen(MENUPAGE_SAVE_FAILED, 0, true, false); + SwitchToNewScreen(MENUPAGE_SAVE_FAILED); break; case SAVESTATUS_ERR_LOAD_OPEN: case SAVESTATUS_ERR_LOAD_READ: case SAVESTATUS_ERR_LOAD_CLOSE: - ChangeScreen(MENUPAGE_LOAD_FAILED, 0, true, false); + SwitchToNewScreen(MENUPAGE_LOAD_FAILED); break; case SAVESTATUS_ERR_DATA_INVALID: - ChangeScreen(MENUPAGE_LOAD_FAILED_2, 0, true, false); + SwitchToNewScreen(MENUPAGE_LOAD_FAILED_2); break; case SAVESTATUS_DELETEFAILED8: case SAVESTATUS_DELETEFAILED9: case SAVESTATUS_DELETEFAILED10: - ChangeScreen(MENUPAGE_DELETE_FAILED, 0, true, false); + SwitchToNewScreen(MENUPAGE_DELETE_FAILED); break; default: break; } @@ -5031,13 +4849,6 @@ CMenuManager::SetHelperText(int text) m_nHelperTextAlpha = 300; } -void -CMenuManager::ShutdownJustMenu() -{ - m_bMenuActive = false; - CTimer::EndUserPause(); -} - float CMenuManager::StretchX(float x) { @@ -5057,81 +4868,132 @@ float CMenuManager::StretchY(float y) return SCREEN_STRETCH_Y(y); } +void +CMenuManager::ProcessFileActions() +{ + if (m_nCurrScreen == MENUPAGE_DELETING) { + bool SlotPopulated = false; + + if (PcSaveHelper.DeleteSlot(m_nCurrSaveSlot)) { + PcSaveHelper.PopulateSlotInfo(); + SlotPopulated = true; + } + + if (SlotPopulated) + SwitchToNewScreen(MENUPAGE_DELETE_SUCCESS); + else + SaveLoadFileError_SetUpErrorScreen(); + } + if (m_nCurrScreen == MENUPAGE_SAVING_IN_PROGRESS) { + int8 SaveSlot = PcSaveHelper.SaveSlot(m_nCurrSaveSlot); + PcSaveHelper.PopulateSlotInfo(); + if (SaveSlot) + SwitchToNewScreen(MENUPAGE_SAVE_SUCCESSFUL); + else + SaveLoadFileError_SetUpErrorScreen(); + } + if (m_nCurrScreen == MENUPAGE_LOADING_IN_PROGRESS) { + if (CheckSlotDataValid(m_nCurrSaveSlot)) { + DoSettingsBeforeStartingAGame(); + m_bWantToLoad = true; + } + else + SaveLoadFileError_SetUpErrorScreen(); + } +} + +// --MIAMI: Done except DxInput things, are they even needed? void CMenuManager::SwitchMenuOnAndOff() { - bool menuWasActive = GetIsMenuActive(); + if (!TheCamera.m_WideScreenOn) { - // Reminder: You need REGISTER_START_BUTTON defined to make it work. - if (CPad::GetPad(0)->GetStartJustDown() -#ifdef FIX_BUGS - && !m_bGameNotLoaded -#endif - || m_bShutDownFrontEndRequested || m_bStartUpFrontEndRequested) { + // Reminder: You need REGISTER_START_BUTTON defined to make it work. + if ((CPad::GetPad(0)->GetStartJustDown() || CPad::GetPad(0)->GetEscapeJustDown()) + && (!m_bMenuActive || m_nCurrScreen == MENUPAGE_PAUSE_MENU || m_nCurrScreen == MENUPAGE_CHOOSE_SAVE_SLOT/* || m_nCurrScreen == 20 */) // TODO(Miami): What is screen 20? + || m_bShutDownFrontEndRequested || m_bStartUpFrontEndRequested) { - m_bMenuActive = !m_bMenuActive; + if (m_nCurrScreen != MENUPAGE_LOADING_IN_PROGRESS) { + DoRWStuffStartOfFrame(0, 0, 0, 0, 0, 0, 255); + DoRWStuffEndOfFrame(); + DoRWStuffStartOfFrame(0, 0, 0, 0, 0, 0, 255); + DoRWStuffEndOfFrame(); + } - if (m_bShutDownFrontEndRequested) - m_bMenuActive = false; - if (m_bStartUpFrontEndRequested) - m_bMenuActive = true; + if (m_bShutDownFrontEndRequested) + m_bMenuActive = false; + else if (m_bStartUpFrontEndRequested) + m_bMenuActive = true; + else + m_bMenuActive = !m_bMenuActive; + + if (m_bMenuActive) { + Initialise(); + LoadAllTextures(); + + // TODO(Miami): DxInput?? + } else { + if (CMBlur::BlurOn) + CMBlur::MotionBlurOpen(Scene.camera); + else + CMBlur::MotionBlurClose(); + DoRWStuffStartOfFrame(0, 0, 0, 0, 0, 0, 255); + DoRWStuffEndOfFrame(); + DoRWStuffStartOfFrame(0, 0, 0, 0, 0, 0, 255); + DoRWStuffEndOfFrame(); + + // TODO(Miami): DxInput?? - if (m_bMenuActive) { - CTimer::StartUserPause(); - } else { #ifdef PS2_LIKE_MENU - bottomBarActive = false; + bottomBarActive = false; #endif -#ifdef FIX_BUGS - ThingsToDoBeforeLeavingPage(); -#endif - ShutdownJustMenu(); - SaveSettings(); - m_bStartUpFrontEndRequested = false; - pControlEdit = nil; - m_bShutDownFrontEndRequested = false; - DisplayComboButtonErrMsg = false; + + m_StatsScrollSpeed = 150.0f; + SaveSettings(); + pControlEdit = nil; + pEditString = nil; + DisplayComboButtonErrMsg = false; + m_bShutDownFrontEndRequested = false; + m_bStartUpFrontEndRequested = false; + m_bWaitingForNewKeyBind = false; #ifdef REGISTER_START_BUTTON - int16 start1 = CPad::GetPad(0)->PCTempJoyState.Start, start2 = CPad::GetPad(0)->PCTempKeyState.Start, - start3 = CPad::GetPad(0)->OldState.Start, start4 = CPad::GetPad(0)->NewState.Start; + int16 start1 = CPad::GetPad(0)->PCTempJoyState.Start, start2 = CPad::GetPad(0)->PCTempKeyState.Start, + start3 = CPad::GetPad(0)->OldState.Start, start4 = CPad::GetPad(0)->NewState.Start; #endif - CPad::GetPad(0)->Clear(false); - CPad::GetPad(1)->Clear(false); + CPad::GetPad(0)->Clear(false); + CPad::GetPad(1)->Clear(false); #ifdef REGISTER_START_BUTTON - CPad::GetPad(0)->PCTempJoyState.Start = start1; - CPad::GetPad(0)->PCTempKeyState.Start = start2; - CPad::GetPad(0)->OldState.Start = start3; - CPad::GetPad(0)->NewState.Start = start4; + CPad::GetPad(0)->PCTempJoyState.Start = start1; + CPad::GetPad(0)->PCTempKeyState.Start = start2; + CPad::GetPad(0)->OldState.Start = start3; + CPad::GetPad(0)->NewState.Start = start4; #endif - m_nCurrScreen = MENUPAGE_NONE; + UnloadTextures(); + CTimer::EndUserPause(); + CTimer::Update(); + m_OnlySaveMenu = false; + } } } // Just entered the save/safe zone - if (m_bSaveMenuActive && !m_bQuitGameNoCD) { - m_bSaveMenuActive = false; + if (m_bActivateSaveMenu) { + DoRWStuffStartOfFrame(0, 0, 0, 0, 0, 0, 255); + DoRWStuffEndOfFrame(); + DoRWStuffStartOfFrame(0, 0, 0, 0, 0, 0, 255); + DoRWStuffEndOfFrame(); + m_bActivateSaveMenu = false; m_bMenuActive = true; - CTimer::StartUserPause(); -#ifdef PS2_SAVE_DIALOG - m_nCurrScreen = MENUPAGE_SAVE; - m_bRenderGameInMenu = true; -#else + m_OnlySaveMenu = true; + + // TODO(Miami): DxInput?? + + Initialise(); + LoadAllTextures(); m_nCurrScreen = MENUPAGE_CHOOSE_SAVE_SLOT; -#endif - PcSaveHelper.PopulateSlotInfo(); m_nCurrOption = 0; } -/* // PS2 leftover - if (m_nCurrScreen != MENUPAGE_SOUND_SETTINGS && gMusicPlaying) - { - DMAudio.StopFrontEndTrack(); - OutputDebugString("FRONTEND AUDIO TRACK STOPPED"); - gMusicPlaying = 0; - } -*/ - if (m_bMenuActive != menuWasActive) - m_bMenuStateChanged = true; m_bStartUpFrontEndRequested = false; m_bShutDownFrontEndRequested = false; @@ -5140,27 +5002,31 @@ CMenuManager::SwitchMenuOnAndOff() void CMenuManager::UnloadTextures() { - if (!m_bSpritesLoaded) - return; + if (m_nCurrScreen == MENUPAGE_SOUND_SETTINGS) + DMAudio.StopFrontEndTrack(); - printf("REMOVE frontend\n"); - for (int i = 0; i < ARRAY_SIZE(FrontendFilenames); ++i) - m_aFrontEndSprites[i].Delete(); + DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_STARTING, 0); + DMAudio.ChangeMusicMode(MUSICMODE_GAME); + if (m_bSpritesLoaded) { + printf("REMOVE frontend\n"); + int frontend = CTxdStore::FindTxdSlot("frontend1"); + for (int i = 0; i < 3; ++i) + m_aFrontEndSprites[i].Delete(); - int frontend = CTxdStore::FindTxdSlot("frontend"); - CTxdStore::RemoveTxd(frontend); + CTxdStore::RemoveTxd(frontend); - printf("REMOVE menu textures\n"); - for (int i = 0; i < ARRAY_SIZE(MenuFilenames); ++i) - m_aMenuSprites[i].Delete(); -#ifdef MENU_MAP - for (int i = 0; i < ARRAY_SIZE(MapFilenames); ++i) - m_aMapSprites[i].Delete(); -#endif - int menu = CTxdStore::FindTxdSlot("menu"); - CTxdStore::RemoveTxd(menu); + if (!m_OnlySaveMenu) { + int frontend2 = CTxdStore::FindTxdSlot("frontend2"); + for (int i = 3; i < NUM_MENU_SPRITES; ++i) + m_aFrontEndSprites[i].Delete(); - m_bSpritesLoaded = false; + CTxdStore::RemoveTxd(frontend2); + } + + m_bSpritesLoaded = false; + } + m_OnlySaveMenu = false; + // TODO(Miami): Place name thing } void @@ -5191,274 +5057,53 @@ CMenuManager::WaitForUserCD() } } -void -CMenuManager::PrintController(void) -{ - // FIX: Originally this function doesn't have StretchX/Y, everything had constant pixel size (due to screen was abandoned early?) - // Also texts and their alignment were very bad, so I tried to make them readable (commented out the original code, and marked the ones I added with X) - - m_aFrontEndSprites[FE_CONTROLLERSH].Draw(MENU_X_LEFT_ALIGNED(160.0f), MENU_Y(160.0f), MENU_X(240.0f), MENU_Y(180.0f), CRGBA(0, 0, 0, 255)); - m_aFrontEndSprites[FE_CONTROLLER].Draw(MENU_X_LEFT_ALIGNED(160.0f), MENU_Y(160.0f), MENU_X(235.2f), MENU_Y(175.2f), CRGBA(255, 255, 255, 255)); - if (m_DisplayControllerOnFoot) { - if (CTimer::GetTimeInMillisecondsPauseMode() & 0x400) - m_aFrontEndSprites[FE_ARROWS1].Draw(MENU_X_LEFT_ALIGNED(160.0f), MENU_Y(160.0f), MENU_X(235.2f), MENU_Y(175.2f), CRGBA(255, 255, 255, 255)); - else - m_aFrontEndSprites[FE_ARROWS3].Draw(MENU_X_LEFT_ALIGNED(160.0f), MENU_Y(160.0f), MENU_X(235.2f), MENU_Y(175.2f), CRGBA(255, 255, 255, 255)); - } else { - if (CTimer::GetTimeInMillisecondsPauseMode() & 0x400) - m_aFrontEndSprites[FE_ARROWS2].Draw(MENU_X_LEFT_ALIGNED(160.0f), MENU_Y(160.0f), MENU_X(235.2f), MENU_Y(175.2f), CRGBA(255, 255, 255, 255)); - else - m_aFrontEndSprites[FE_ARROWS4].Draw(MENU_X_LEFT_ALIGNED(160.0f), MENU_Y(160.0f), MENU_X(235.2f), MENU_Y(175.2f), CRGBA(255, 255, 255, 255)); - } - - CFont::SetFontStyle(FONT_LOCALE(FONT_BANK)); // X - - // CFont::SetScale(0.4f, 0.4f); - CFont::SetScale(MENU_X(SMALLESTTEXT_X_SCALE), MENU_Y(SMALLESTTEXT_Y_SCALE)); // X - - // CFont::SetColor(CRGBA(128, 128, 128, FadeIn(255))); - CFont::SetDropColor(CRGBA(0, 0, 0, FadeIn(255))); // X - CFont::SetDropShadowPosition(1); // X - CFont::SetColor(CRGBA(255, 255, 255, FadeIn(255))); // X - - if (m_DisplayControllerOnFoot) { - switch (CPad::GetPad(0)->Mode) { - case 0: - CFont::SetRightJustifyOn(); // X - CFont::PrintString(MENU_X_LEFT_ALIGNED(210.0f), MENU_Y(146.0f), TheText.Get("FEC_CWL")); - CFont::PrintString(MENU_X_LEFT_ALIGNED(156.0f), MENU_Y(185.0f), TheText.Get("FEC_LOF")); - CFont::PrintString(MENU_X_LEFT_ALIGNED(156.0f), MENU_Y(225.0f), TheText.Get("FEC_MOV")); - CFont::PrintString(MENU_X_LEFT_ALIGNED(156.0f), MENU_Y(257.0f), TheText.Get("FEC_MOV")); - CFont::SetJustifyOn(); // X - CFont::PrintString(MENU_X_LEFT_ALIGNED(263.0f), MENU_Y(301.0f), TheText.Get("FEC_CAM")); - CFont::PrintString(MENU_X_LEFT_ALIGNED(290.0f), MENU_Y(288.0f), TheText.Get("FEC_PAU")); - CFont::PrintString(MENU_X_LEFT_ALIGNED(344.0f), MENU_Y(146.0f), TheText.Get("FEC_CWR")); - CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(185.0f), TheText.Get("FEC_TAR")); - CFont::SetRightJustifyOn(); // X - CFont::PrintString(MENU_X_LEFT_ALIGNED(304.0f), MENU_Y(178.0f), TheText.Get("FEC_JUM")); - CFont::SetJustifyOn(); // X - CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(212.0f), TheText.Get("FEC_ENV")); - CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(225.0f), TheText.Get("FEC_ATT")); - CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(238.0f), TheText.Get("FEC_RUN")); - CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(254.0f), TheText.Get("FEC_FPC")); - CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(269.0f), TheText.Get("FEC_LB3")); - CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(282.0f), TheText.Get("FEC_R3")); - break; - case 1: - CFont::SetRightJustifyOn(); // X - CFont::PrintString(MENU_X_LEFT_ALIGNED(210.0f), MENU_Y(146.0f), TheText.Get("FEC_CWL")); - CFont::PrintString(MENU_X_LEFT_ALIGNED(156.0f), MENU_Y(185.0f), TheText.Get("FEC_LOF")); - CFont::PrintString(MENU_X_LEFT_ALIGNED(156.0f), MENU_Y(225.0f), TheText.Get("FEC_CAM")); - CFont::PrintString(MENU_X_LEFT_ALIGNED(156.0f), MENU_Y(257.0f), TheText.Get("FEC_MOV")); - CFont::SetJustifyOn(); // X - CFont::PrintString(MENU_X_LEFT_ALIGNED(263.0f), MENU_Y(301.0f), TheText.Get("FEC_NA")); - CFont::PrintString(MENU_X_LEFT_ALIGNED(290.0f), MENU_Y(288.0f), TheText.Get("FEC_PAU")); - CFont::PrintString(MENU_X_LEFT_ALIGNED(344.0f), MENU_Y(146.0f), TheText.Get("FEC_CWR")); - CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(185.0f), TheText.Get("FEC_TAR")); - CFont::SetRightJustifyOn(); // X - CFont::PrintString(MENU_X_LEFT_ALIGNED(304.0f), MENU_Y(178.0f), TheText.Get("FEC_JUM")); - CFont::SetJustifyOn(); // X - CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(212.0f), TheText.Get("FEC_ENV")); - CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(225.0f), TheText.Get("FEC_ATT")); - CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(238.0f), TheText.Get("FEC_RUN")); - CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(254.0f), TheText.Get("FEC_FPC")); - CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(269.0f), TheText.Get("FEC_LB3")); - CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(282.0f), TheText.Get("FEC_R3")); - break; - case 2: - CFont::SetRightJustifyOn(); // X - CFont::PrintString(MENU_X_LEFT_ALIGNED(210.0f), MENU_Y(146.0f), TheText.Get("FEC_CWL")); - CFont::PrintString(MENU_X_LEFT_ALIGNED(156.0f), MENU_Y(185.0f), TheText.Get("FEC_ENV")); - CFont::PrintString(MENU_X_LEFT_ALIGNED(156.0f), MENU_Y(225.0f), TheText.Get("FEC_MOV")); - CFont::PrintString(MENU_X_LEFT_ALIGNED(156.0f), MENU_Y(257.0f), TheText.Get("FEC_MOV")); - CFont::SetJustifyOn(); // X - CFont::PrintString(MENU_X_LEFT_ALIGNED(263.0f), MENU_Y(301.0f), TheText.Get("FEC_CAM")); - CFont::PrintString(MENU_X_LEFT_ALIGNED(290.0f), MENU_Y(288.0f), TheText.Get("FEC_PAU")); - CFont::PrintString(MENU_X_LEFT_ALIGNED(344.0f), MENU_Y(146.0f), TheText.Get("FEC_CWR")); - CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(185.0f), TheText.Get("FEC_TAR")); - CFont::SetRightJustifyOn(); // X - CFont::PrintString(MENU_X_LEFT_ALIGNED(304.0f), MENU_Y(178.0f), TheText.Get("FEC_JUM")); - CFont::SetJustifyOn(); // X - CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(212.0f), TheText.Get("FEC_LOF")); - CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(225.0f), TheText.Get("FEC_RUN")); - CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(238.0f), TheText.Get("FEC_ATT")); - CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(254.0f), TheText.Get("FEC_FPC")); - CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(269.0f), TheText.Get("FEC_LB3")); - CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(282.0f), TheText.Get("FEC_R3")); - break; - case 3: - CFont::SetRightJustifyOn(); // X - CFont::PrintString(MENU_X_LEFT_ALIGNED(210.0f), MENU_Y(146.0f), TheText.Get("FEC_CWL")); - CFont::PrintString(MENU_X_LEFT_ALIGNED(156.0f), MENU_Y(185.0f), TheText.Get("FEC_TAR")); - CFont::PrintString(MENU_X_LEFT_ALIGNED(156.0f), MENU_Y(225.0f), TheText.Get("FEC_NA")); - CFont::PrintString(MENU_X_LEFT_ALIGNED(156.0f), MENU_Y(257.0f), TheText.Get("FEC_MOV")); - CFont::SetJustifyOn(); // X - CFont::PrintString(MENU_X_LEFT_ALIGNED(263.0f), MENU_Y(301.0f), TheText.Get("FEC_CAM")); - CFont::PrintString(MENU_X_LEFT_ALIGNED(290.0f), MENU_Y(288.0f), TheText.Get("FEC_PAU")); - CFont::PrintString(MENU_X_LEFT_ALIGNED(344.0f), MENU_Y(146.0f), TheText.Get("FEC_CWR")); - CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(185.0f), TheText.Get("FEC_TAR")); - CFont::SetRightJustifyOn(); // X - CFont::PrintString(MENU_X_LEFT_ALIGNED(304.0f), MENU_Y(178.0f), TheText.Get("FEC_JUM")); - CFont::SetJustifyOn(); // X - CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(212.0f), TheText.Get("FEC_LOF")); - CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(225.0f), TheText.Get("FEC_RUN")); - CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(238.0f), TheText.Get("FEC_ATT")); - CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(254.0f), TheText.Get("FEC_FPC")); - CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(269.0f), TheText.Get("FEC_LB3")); - CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(282.0f), TheText.Get("FEC_R3")); - break; - default: - return; - } - } else { - switch (CPad::GetPad(0)->Mode) { - case 0: - CFont::SetRightJustifyOn(); // X - CFont::PrintString(MENU_X_LEFT_ALIGNED(210.0f), MENU_Y(146.0f), TheText.Get("FEC_LL")); - CFont::PrintString(MENU_X_LEFT_ALIGNED(156.0f), MENU_Y(185.0f), TheText.Get("FEC_RSC")); - CFont::PrintString(MENU_X_LEFT_ALIGNED(156.0f), MENU_Y(225.0f), TheText.Get("FEC_VES")); - CFont::PrintString(MENU_X_LEFT_ALIGNED(156.0f), MENU_Y(257.0f), TheText.Get("FEC_VES")); - CFont::SetJustifyOn(); // X - CFont::PrintString(MENU_X_LEFT_ALIGNED(263.0f), MENU_Y(301.0f), TheText.Get("FEC_HO3")); - CFont::PrintString(MENU_X_LEFT_ALIGNED(290.0f), MENU_Y(288.0f), TheText.Get("FEC_CAM")); - CFont::PrintString(MENU_X_LEFT_ALIGNED(344.0f), MENU_Y(146.0f), TheText.Get("FEC_PAU")); - CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(185.0f), TheText.Get("FEC_LB")); - CFont::SetRightJustifyOn(); // X - CFont::PrintString(MENU_X_LEFT_ALIGNED(304.0f), MENU_Y(178.0f), TheText.Get("FEC_LR")); - CFont::SetJustifyOn(); // X - CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(212.0f), TheText.Get("FEC_HAB")); - CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(225.0f), TheText.Get("FEC_BRA")); - CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(238.0f), TheText.Get("FEC_EXV")); - CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(254.0f), TheText.Get("FEC_CAW")); - CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(269.0f), TheText.Get("FEC_ACC")); - CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(282.0f), TheText.Get("FEC_TUC")); - // FIX: Coordinates of this line is undefined in PC... - CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(304.0f), TheText.Get("FEC_SM3")); - break; - case 1: - CFont::SetRightJustifyOn(); // X - CFont::PrintString(MENU_X_LEFT_ALIGNED(210.0f), MENU_Y(146.0f), TheText.Get("FEC_LL")); - CFont::PrintString(MENU_X_LEFT_ALIGNED(156.0f), MENU_Y(185.0f), TheText.Get("FEC_HOR")); - CFont::PrintString(MENU_X_LEFT_ALIGNED(156.0f), MENU_Y(225.0f), TheText.Get("FEC_CAM")); - CFont::PrintString(MENU_X_LEFT_ALIGNED(156.0f), MENU_Y(257.0f), TheText.Get("FEC_VES")); - CFont::SetJustifyOn(); // X - CFont::PrintString(MENU_X_LEFT_ALIGNED(263.0f), MENU_Y(301.0f), TheText.Get("FEC_NA")); - CFont::PrintString(MENU_X_LEFT_ALIGNED(290.0f), MENU_Y(288.0f), TheText.Get("FEC_RSC")); - CFont::PrintString(MENU_X_LEFT_ALIGNED(344.0f), MENU_Y(146.0f), TheText.Get("FEC_PAU")); - CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(185.0f), TheText.Get("FEC_LB")); - CFont::SetRightJustifyOn(); // X - CFont::PrintString(MENU_X_LEFT_ALIGNED(304.0f), MENU_Y(178.0f), TheText.Get("FEC_LR")); - CFont::SetJustifyOn(); // X - CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(212.0f), TheText.Get("FEC_HAB")); - CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(225.0f), TheText.Get("FEC_BRA")); - CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(238.0f), TheText.Get("FEC_EXV")); - CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(254.0f), TheText.Get("FEC_CAW")); - CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(269.0f), TheText.Get("FEC_ACC")); - CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(282.0f), TheText.Get("FEC_TUC")); - // FIX: Coordinates of this line is undefined in PC... - CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(304.0f), TheText.Get("FEC_SM3")); - break; - case 2: - CFont::SetRightJustifyOn(); // X - CFont::PrintString(MENU_X_LEFT_ALIGNED(210.0f), MENU_Y(146.0f), TheText.Get("FEC_LL")); - CFont::PrintString(MENU_X_LEFT_ALIGNED(156.0f), MENU_Y(185.0f), TheText.Get("FEC_EXV")); - CFont::PrintString(MENU_X_LEFT_ALIGNED(156.0f), MENU_Y(225.0f), TheText.Get("FEC_VES")); - CFont::PrintString(MENU_X_LEFT_ALIGNED(156.0f), MENU_Y(257.0f), TheText.Get("FEC_VES")); - CFont::SetJustifyOn(); // X - CFont::PrintString(MENU_X_LEFT_ALIGNED(263.0f), MENU_Y(301.0f), TheText.Get("FEC_RS3")); - CFont::PrintString(MENU_X_LEFT_ALIGNED(290.0f), MENU_Y(288.0f), TheText.Get("FEC_CAM")); - CFont::PrintString(MENU_X_LEFT_ALIGNED(344.0f), MENU_Y(146.0f), TheText.Get("FEC_PAU")); - CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(185.0f), TheText.Get("FEC_LB")); - CFont::SetRightJustifyOn(); // X - CFont::PrintString(MENU_X_LEFT_ALIGNED(304.0f), MENU_Y(178.0f), TheText.Get("FEC_LR")); - CFont::SetJustifyOn(); // X - CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(212.0f), TheText.Get("FEC_HOR")); - CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(225.0f), TheText.Get("FEC_BRA")); - CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(238.0f), TheText.Get("FEC_HAB")); - CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(254.0f), TheText.Get("FEC_CAW")); - CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(269.0f), TheText.Get("FEC_ACC")); - CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(282.0f), TheText.Get("FEC_TUC")); - // FIX: Coordinates of this line is undefined in PC... - CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(304.0f), TheText.Get("FEC_SM3")); - break; - case 3: - CFont::SetRightJustifyOn(); // X - CFont::PrintString(MENU_X_LEFT_ALIGNED(210.0f), MENU_Y(146.0f), TheText.Get("FEC_LL")); - CFont::PrintString(MENU_X_LEFT_ALIGNED(156.0f), MENU_Y(185.0f), TheText.Get("FEC_HAB")); - CFont::PrintString(MENU_X_LEFT_ALIGNED(156.0f), MENU_Y(225.0f), TheText.Get("FEC_TUC")); - CFont::PrintString(MENU_X_LEFT_ALIGNED(156.0f), MENU_Y(257.0f), TheText.Get("FEC_VES")); - CFont::SetJustifyOn(); // X - CFont::PrintString(MENU_X_LEFT_ALIGNED(263.0f), MENU_Y(301.0f), TheText.Get("FEC_HO3")); - CFont::PrintString(MENU_X_LEFT_ALIGNED(290.0f), MENU_Y(288.0f), TheText.Get("FEC_CAM")); - CFont::PrintString(MENU_X_LEFT_ALIGNED(344.0f), MENU_Y(146.0f), TheText.Get("FEC_PAU")); - CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(185.0f), TheText.Get("FEC_LB")); - CFont::SetRightJustifyOn(); // X - CFont::PrintString(MENU_X_LEFT_ALIGNED(304.0f), MENU_Y(178.0f), TheText.Get("FEC_LR")); - CFont::SetJustifyOn(); // X - CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(212.0f), TheText.Get("FEC_CAW")); - CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(225.0f), TheText.Get("FEC_SMT")); - CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(238.0f), TheText.Get("FEC_EXV")); - CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(254.0f), TheText.Get("FEC_RSC")); - CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(269.0f), TheText.Get("FEC_NA")); - CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(282.0f), TheText.Get("FEC_ACC")); - // FIX: Coordinates of this line is undefined in PC... - CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(304.0f), TheText.Get("FEC_BRA")); - break; - default: - return; - } - } - - CFont::SetDropShadowPosition(0); // X -} - #ifdef MENU_MAP #define ZOOM(x, y, in) \ do { \ - if(fMapSize > SCREEN_HEIGHT * 3.0f && in) \ + if(m_fMapSize > SCREEN_HEIGHT * 3.0f && in) \ break; \ float z2 = in? 1.1f : 1.f/1.1f; \ - fMapCenterX += (x - fMapCenterX) * (1.0f - z2); \ - fMapCenterY += (y - fMapCenterY) * (1.0f - z2); \ + m_fMapCenterX += (x - m_fMapCenterX) * (1.0f - z2); \ + m_fMapCenterY += (y - m_fMapCenterY) * (1.0f - z2); \ \ - if (fMapSize < SCREEN_HEIGHT / 2 && !in) \ + if (m_fMapSize < SCREEN_HEIGHT / 2 && !in) \ break; \ \ - fMapSize *= z2; \ + m_fMapSize *= z2; \ } while(0) \ void CMenuManager::PrintMap(void) { CFont::SetJustifyOn(); - bMenuMapActive = true; + m_bMenuMapActive = true; CRadar::InitFrontEndMap(); // Just entered to map if (!bMapLoaded) { - fMapSize = SCREEN_HEIGHT * 2.0f; - fMapCenterX = 0.0f; - fMapCenterY = 0.0f; + m_fMapSize = SCREEN_HEIGHT * 2.0f; + m_fMapCenterX = 0.0f; + m_fMapCenterY = 0.0f; CVector2D radarSpacePlayer; CVector2D screenSpacePlayer; CRadar::TransformRealWorldPointToRadarSpace(radarSpacePlayer, CVector2D(FindPlayerCoors())); CRadar::TransformRadarPointToScreenSpace(screenSpacePlayer, radarSpacePlayer); - fMapCenterX = (-screenSpacePlayer.x) + SCREEN_WIDTH / 2; - fMapCenterY = (-screenSpacePlayer.y) + SCREEN_HEIGHT / 2; + m_fMapCenterX = (-screenSpacePlayer.x) + SCREEN_WIDTH / 2; + m_fMapCenterY = (-screenSpacePlayer.y) + SCREEN_HEIGHT / 2; bMapMouseShownOnce = false; bMapLoaded = true; // Let's wait for a frame to not toggle the waypoint if (CPad::GetPad(0)->NewState.Cross) { - bMenuMapActive = false; + m_bMenuMapActive = false; return; } } - // Because fMapSize is half of the map length, and map consists of 3x3 tiles. - float halfTile = fMapSize / 3.0f; + // Because m_fMapSize is half of the map length, and map consists of 3x3 tiles. + float halfTile = m_fMapSize / 3.0f; // Darken background a bit CSprite2d::DrawRect(CRect(0, 0, @@ -5467,49 +5112,49 @@ CMenuManager::PrintMap(void) RwRenderStateSet(rwRENDERSTATETEXTUREFILTER, (void*)rwFILTERLINEAR); - if (SCREEN_WIDTH >= fMapCenterX - fMapSize || SCREEN_HEIGHT >= fMapCenterY - fMapSize) { - m_aMapSprites[MAPTOP1].Draw(CRect(fMapCenterX - fMapSize, fMapCenterY - fMapSize, - fMapCenterX - halfTile, fMapCenterY - halfTile), CRGBA(255, 255, 255, FadeIn(255))); + if (SCREEN_WIDTH >= m_fMapCenterX - m_fMapSize || SCREEN_HEIGHT >= m_fMapCenterY - m_fMapSize) { + m_aFrontEndSprites[MENUSPRITE_MAPTOP01].Draw(CRect(m_fMapCenterX - m_fMapSize, m_fMapCenterY - m_fMapSize, + m_fMapCenterX - halfTile, m_fMapCenterY - halfTile), CRGBA(255, 255, 255, FadeIn(255))); } - if (SCREEN_WIDTH >= fMapCenterX - halfTile || SCREEN_HEIGHT >= fMapCenterY - fMapSize) { - m_aMapSprites[MAPTOP2].Draw(CRect(fMapCenterX - halfTile, fMapCenterY - fMapSize, - fMapCenterX + halfTile, fMapCenterY - halfTile), CRGBA(255, 255, 255, FadeIn(255))); + if (SCREEN_WIDTH >= m_fMapCenterX - halfTile || SCREEN_HEIGHT >= m_fMapCenterY - m_fMapSize) { + m_aFrontEndSprites[MENUSPRITE_MAPTOP02].Draw(CRect(m_fMapCenterX - halfTile, m_fMapCenterY - m_fMapSize, + m_fMapCenterX + halfTile, m_fMapCenterY - halfTile), CRGBA(255, 255, 255, FadeIn(255))); } - if (SCREEN_WIDTH >= fMapCenterX + halfTile || SCREEN_HEIGHT >= fMapCenterY - fMapSize) { - m_aMapSprites[MAPTOP3].Draw(CRect(fMapCenterX + halfTile, fMapCenterY - fMapSize, - fMapCenterX + fMapSize, fMapCenterY - halfTile), CRGBA(255, 255, 255, FadeIn(255))); + if (SCREEN_WIDTH >= m_fMapCenterX + halfTile || SCREEN_HEIGHT >= m_fMapCenterY - m_fMapSize) { + m_aFrontEndSprites[MENUSPRITE_MAPTOP03].Draw(CRect(m_fMapCenterX + halfTile, m_fMapCenterY - m_fMapSize, + m_fMapCenterX + m_fMapSize, m_fMapCenterY - halfTile), CRGBA(255, 255, 255, FadeIn(255))); } - if (SCREEN_WIDTH >= fMapCenterX - fMapSize || SCREEN_HEIGHT >= fMapCenterY - halfTile) { - m_aMapSprites[MAPMID1].Draw(CRect(fMapCenterX - fMapSize, fMapCenterY - halfTile, - fMapCenterX - halfTile, fMapCenterY + halfTile), CRGBA(255, 255, 255, FadeIn(255))); + if (SCREEN_WIDTH >= m_fMapCenterX - m_fMapSize || SCREEN_HEIGHT >= m_fMapCenterY - halfTile) { + m_aFrontEndSprites[MENUSPRITE_MAPMID01].Draw(CRect(m_fMapCenterX - m_fMapSize, m_fMapCenterY - halfTile, + m_fMapCenterX - halfTile, m_fMapCenterY + halfTile), CRGBA(255, 255, 255, FadeIn(255))); } - if (SCREEN_WIDTH >= fMapCenterX - halfTile || SCREEN_HEIGHT >= fMapCenterY - halfTile) { - m_aMapSprites[MAPMID2].Draw(CRect(fMapCenterX - halfTile, fMapCenterY - halfTile, - fMapCenterX + halfTile, fMapCenterY + halfTile), CRGBA(255, 255, 255, FadeIn(255))); + if (SCREEN_WIDTH >= m_fMapCenterX - halfTile || SCREEN_HEIGHT >= m_fMapCenterY - halfTile) { + m_aFrontEndSprites[MENUSPRITE_MAPMID02].Draw(CRect(m_fMapCenterX - halfTile, m_fMapCenterY - halfTile, + m_fMapCenterX + halfTile, m_fMapCenterY + halfTile), CRGBA(255, 255, 255, FadeIn(255))); } - if (SCREEN_WIDTH >= fMapCenterX + halfTile || SCREEN_HEIGHT >= fMapCenterY - halfTile) { - m_aMapSprites[MAPMID3].Draw(CRect(fMapCenterX + halfTile, fMapCenterY - halfTile, - fMapCenterX + fMapSize, fMapCenterY + halfTile), CRGBA(255, 255, 255, FadeIn(255))); + if (SCREEN_WIDTH >= m_fMapCenterX + halfTile || SCREEN_HEIGHT >= m_fMapCenterY - halfTile) { + m_aFrontEndSprites[MENUSPRITE_MAPMID03].Draw(CRect(m_fMapCenterX + halfTile, m_fMapCenterY - halfTile, + m_fMapCenterX + m_fMapSize, m_fMapCenterY + halfTile), CRGBA(255, 255, 255, FadeIn(255))); } - if (SCREEN_WIDTH >= fMapCenterX - fMapSize || SCREEN_HEIGHT >= fMapCenterY + halfTile) { - m_aMapSprites[MAPBOT1].Draw(CRect(fMapCenterX - fMapSize, fMapCenterY + halfTile, - fMapCenterX - halfTile, fMapCenterY + fMapSize), CRGBA(255, 255, 255, FadeIn(255))); + if (SCREEN_WIDTH >= m_fMapCenterX - m_fMapSize || SCREEN_HEIGHT >= m_fMapCenterY + halfTile) { + m_aFrontEndSprites[MENUSPRITE_MAPBOT01].Draw(CRect(m_fMapCenterX - m_fMapSize, m_fMapCenterY + halfTile, + m_fMapCenterX - halfTile, m_fMapCenterY + m_fMapSize), CRGBA(255, 255, 255, FadeIn(255))); } - if (SCREEN_WIDTH >= fMapCenterX - halfTile || SCREEN_HEIGHT >= fMapCenterY + halfTile) { - m_aMapSprites[MAPBOT2].Draw(CRect(fMapCenterX - halfTile, fMapCenterY + halfTile, - fMapCenterX + halfTile, fMapCenterY + fMapSize), CRGBA(255, 255, 255, FadeIn(255))); + if (SCREEN_WIDTH >= m_fMapCenterX - halfTile || SCREEN_HEIGHT >= m_fMapCenterY + halfTile) { + m_aFrontEndSprites[MENUSPRITE_MAPBOT02].Draw(CRect(m_fMapCenterX - halfTile, m_fMapCenterY + halfTile, + m_fMapCenterX + halfTile, m_fMapCenterY + m_fMapSize), CRGBA(255, 255, 255, FadeIn(255))); } - if (SCREEN_WIDTH >= fMapCenterX + halfTile || SCREEN_HEIGHT >= fMapCenterY + halfTile) { - m_aMapSprites[MAPBOT3].Draw(CRect(fMapCenterX + halfTile, fMapCenterY + halfTile, - fMapCenterX + fMapSize, fMapCenterY + fMapSize), CRGBA(255, 255, 255, FadeIn(255))); + if (SCREEN_WIDTH >= m_fMapCenterX + halfTile || SCREEN_HEIGHT >= m_fMapCenterY + halfTile) { + m_aFrontEndSprites[MENUSPRITE_MAPBOT03].Draw(CRect(m_fMapCenterX + halfTile, m_fMapCenterY + halfTile, + m_fMapCenterX + m_fMapSize, m_fMapCenterY + m_fMapSize), CRGBA(255, 255, 255, FadeIn(255))); } CRadar::DrawBlips(); @@ -5533,34 +5178,35 @@ CMenuManager::PrintMap(void) CRGBA(0, 0, 0, 150)); if (CPad::GetPad(0)->GetRightMouseJustDown() || CPad::GetPad(0)->GetCrossJustDown()) { - if (mapPoint.y > fMapCenterY - fMapSize && mapPoint.y < fMapCenterY + fMapSize && - mapPoint.x > fMapCenterX - fMapSize && mapPoint.x < fMapCenterX + fMapSize) { + if (mapPoint.y > m_fMapCenterY - m_fMapSize && mapPoint.y < m_fMapCenterY + m_fMapSize && + mapPoint.x > m_fMapCenterX - m_fMapSize && mapPoint.x < m_fMapCenterX + m_fMapSize) { - float diffX = fMapCenterX - fMapSize, diffY = fMapCenterY - fMapSize; - float x = ((mapPoint.x - diffX) / (fMapSize * 2)) * 4000.0f - 2000.0f; - float y = 2000.0f - ((mapPoint.y - diffY) / (fMapSize * 2)) * 4000.0f; + // Don't ask me the meanings, I don't know. Found them by trying + float diffX = m_fMapCenterX - m_fMapSize, diffY = m_fMapCenterY - m_fMapSize; + float x = ((mapPoint.x - diffX) / (m_fMapSize * 2)) * (WORLD_SIZE_X / MENU_MAP_WIDTH_SCALE) - (WORLD_SIZE_X / 2 + MENU_MAP_LEFT_OFFSET * MENU_MAP_LENGTH_UNIT); + float y = (WORLD_SIZE_Y / 2 - MENU_MAP_TOP_OFFSET * MENU_MAP_LENGTH_UNIT) - ((mapPoint.y - diffY) / (m_fMapSize * 2)) * (WORLD_SIZE_Y / MENU_MAP_HEIGHT_SCALE); CRadar::ToggleTargetMarker(x, y); DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SUCCESS, 0); } } if (CPad::GetPad(0)->GetLeftMouse()) { - fMapCenterX += m_nMousePosX - m_nMouseOldPosX; - fMapCenterY += m_nMousePosY - m_nMouseOldPosY; + m_fMapCenterX += m_nMousePosX - m_nMouseOldPosX; + m_fMapCenterY += m_nMousePosY - m_nMouseOldPosY; } else if (CPad::GetPad(0)->GetLeft() || CPad::GetPad(0)->GetDPadLeft()) { - fMapCenterX += 15.0f; + m_fMapCenterX += 15.0f; } else if (CPad::GetPad(0)->GetRight() || CPad::GetPad(0)->GetDPadRight()) { - fMapCenterX -= 15.0f; + m_fMapCenterX -= 15.0f; } else if (CPad::GetPad(0)->GetLeftStickX()) { - fMapCenterX -= CPad::GetPad(0)->GetLeftStickX() / 128.0f * 20.0f; + m_fMapCenterX -= CPad::GetPad(0)->GetLeftStickX() / 128.0f * 20.0f; } if (CPad::GetPad(0)->GetUp() || CPad::GetPad(0)->GetDPadUp()) { - fMapCenterY += 15.0f; + m_fMapCenterY += 15.0f; } else if (CPad::GetPad(0)->GetDown() || CPad::GetPad(0)->GetDPadDown()) { - fMapCenterY -= 15.0f; + m_fMapCenterY -= 15.0f; } else if (CPad::GetPad(0)->GetLeftStickY()) { - fMapCenterY -= CPad::GetPad(0)->GetLeftStickY() / 128.0f * 20.0f; + m_fMapCenterY -= CPad::GetPad(0)->GetLeftStickY() / 128.0f * 20.0f; } if (CPad::GetPad(0)->GetMouseWheelDown() || CPad::GetPad(0)->GetPageDown() || CPad::GetPad(0)->GetRightShoulder2()) { @@ -5575,25 +5221,26 @@ CMenuManager::PrintMap(void) ZOOM(SCREEN_WIDTH / 2, SCREEN_HEIGHT / 2, true); } - if (fMapCenterX - fMapSize > SCREEN_WIDTH / 2) - fMapCenterX = fMapSize + SCREEN_WIDTH / 2; + if (m_fMapCenterX - m_fMapSize > SCREEN_WIDTH / 2) + m_fMapCenterX = m_fMapSize + SCREEN_WIDTH / 2; - if (fMapCenterX + fMapSize < SCREEN_WIDTH / 2) - fMapCenterX = SCREEN_WIDTH / 2 - fMapSize; + if (m_fMapCenterX + m_fMapSize < SCREEN_WIDTH / 2) + m_fMapCenterX = SCREEN_WIDTH / 2 - m_fMapSize; - if (fMapCenterY + fMapSize < SCREEN_HEIGHT - MENU_Y(60.0f)) - fMapCenterY = SCREEN_HEIGHT - MENU_Y(60.0f) - fMapSize; + if (m_fMapCenterY + m_fMapSize < SCREEN_HEIGHT - MENU_Y(60.0f)) + m_fMapCenterY = SCREEN_HEIGHT - MENU_Y(60.0f) - m_fMapSize; - fMapCenterY = Min(fMapCenterY, fMapSize); // To not show beyond north border + if (m_fMapCenterY - m_fMapSize > SCREEN_HEIGHT / 2) + m_fMapCenterY = SCREEN_HEIGHT / 2 + m_fMapSize; - bMenuMapActive = false; + m_bMenuMapActive = false; // CFont::SetWrapx(MENU_X_RIGHT_ALIGNED(5.0f)); // From VC // CFont::SetRightJustifyWrap(10.0f); CSprite2d::DrawRect(CRect(MENU_X(14.0f), SCREEN_STRETCH_FROM_BOTTOM(95.0f), SCREEN_STRETCH_FROM_RIGHT(11.0f), SCREEN_STRETCH_FROM_BOTTOM(59.0f)), - CRGBA(235, 170, 50, 255)); + CRGBA(MAPINFOBOX_COLOR.r, MAPINFOBOX_COLOR.g, MAPINFOBOX_COLOR.b, MAPINFOBOX_COLOR.a)); CFont::SetScale(MENU_X(0.4f), MENU_Y(0.7f)); CFont::SetFontStyle(FONT_LOCALE(FONT_BANK)); @@ -5654,9 +5301,7 @@ CMenuManager::ConstructStatLine(int rowIdx) STAT_LINE("PL_STAT", nil, false, nil); - int percentCompleted = (CStats::TotalProgressInGame == 0 ? 0 : - CStats::ProgressMade * 100.0f / (CGame::nastyGame ? CStats::TotalProgressInGame : CStats::TotalProgressInGame - 1)); - percentCompleted = Min(percentCompleted, 100); + int percentCompleted = CStats::GetPercentageProgress(); STAT_LINE("PER_COM", &percentCompleted, false, nil); STAT_LINE("NMISON", &CStats::MissionsGiven, false, nil); diff --git a/src/core/Frontend.h b/src/core/Frontend.h index 16da5cb1..e40efeea 100644 --- a/src/core/Frontend.h +++ b/src/core/Frontend.h @@ -7,8 +7,8 @@ #define MENUHEADER_POS_Y 75.0f #define MENUHEADER_HEIGHT 1.3f #else -#define MENUHEADER_POS_X 35.0f -#define MENUHEADER_POS_Y 93.0f +#define MENUHEADER_POS_X 10.0f +#define MENUHEADER_POS_Y 10.0f #define MENUHEADER_HEIGHT 1.6f #endif #define MENUHEADER_WIDTH 0.84f @@ -20,7 +20,7 @@ #define MENURADIO_ICON_SCALE 60.0f -#define MENUSLIDER_X 256.0f +#define MENUSLIDER_X 128.0f #define MENUSLIDER_UNK 256.0f #define BIGTEXT_X_SCALE 0.75f @@ -95,62 +95,34 @@ enum eLanguages #endif }; -enum eFrontendSprites -{ - FE2_MAINPANEL_UL, - FE2_MAINPANEL_UR, - FE2_MAINPANEL_DL, - FE2_MAINPANEL_DR, - FE2_MAINPANEL_DR2, - FE2_TABACTIVE, - FE_ICONBRIEF, - FE_ICONSTATS, - FE_ICONCONTROLS, - FE_ICONSAVE, - FE_ICONAUDIO, - FE_ICONDISPLAY, - FE_ICONLANGUAGE, - FE_CONTROLLER, - FE_CONTROLLERSH, - FE_ARROWS1, - FE_ARROWS2, - FE_ARROWS3, - FE_ARROWS4, - FE_RADIO1, - FE_RADIO2, - FE_RADIO3, - FE_RADIO4, - FE_RADIO5, - FE_RADIO6, - FE_RADIO7, - FE_RADIO8, - FE_RADIO9, - - NUM_FE_SPRITES -}; - enum eMenuSprites { - MENUSPRITE_CONNECTION, - MENUSPRITE_FINDGAME, - MENUSPRITE_HOSTGAME, - MENUSPRITE_MAINMENU, - MENUSPRITE_PLAYERSET, - MENUSPRITE_SINGLEPLAYER, - MENUSPRITE_MULTIPLAYER, - MENUSPRITE_DMALOGO, - MENUSPRITE_GTALOGO, - MENUSPRITE_RSTARLOGO, - MENUSPRITE_GAMESPY, + MENUSPRITE_BACKGROUND, + MENUSPRITE_VCLOGO, MENUSPRITE_MOUSE, - MENUSPRITE_MOUSET, - MENUSPRITE_MP3LOGO, + MENUSPRITE_MAPTOP01, + MENUSPRITE_MAPTOP02, + MENUSPRITE_MAPTOP03, + MENUSPRITE_MAPMID01, + MENUSPRITE_MAPMID02, + MENUSPRITE_MAPMID03, + MENUSPRITE_MAPBOT01, + MENUSPRITE_MAPBOT02, + MENUSPRITE_MAPBOT03, + MENUSPRITE_WILDSTYLE, + MENUSPRITE_FLASH, + MENUSPRITE_KCHAT, + MENUSPRITE_FEVER, + MENUSPRITE_VROCK, + MENUSPRITE_VCPR, + MENUSPRITE_ESPANTOSO, + MENUSPRITE_EMOTION, + MENUSPRITE_WAVE, + MENUSPRITE_MP3, MENUSPRITE_DOWNOFF, MENUSPRITE_DOWNON, MENUSPRITE_UPOFF, MENUSPRITE_UPON, - MENUSPRITE_GTA3LOGO, - MENUSPRITE_UNUSED, NUM_MENU_SPRITES }; @@ -169,22 +141,6 @@ enum eSaveSlot SAVESLOT_LABEL = 36 }; -#ifdef MENU_MAP -enum MapSprites -{ - MAPMID1, - MAPMID2, - MAPMID3, - MAPBOT1, - MAPBOT2, - MAPBOT3, - MAPTOP1, - MAPTOP2, - MAPTOP3, - NUM_MAP_SPRITES -}; -#endif - enum eMenuScreen { MENUPAGE_DISABLED = -1, @@ -372,7 +328,10 @@ enum eMenuAction MENUACTION_LANG_JAP, #endif #ifdef IMPROVED_VIDEOMODE - MENUACTION_SCREENMODE + MENUACTION_SCREENMODE, +#endif +#ifdef FREE_CAM + MENUACTION_FREECAM #endif }; @@ -472,69 +431,195 @@ struct CMenuScreen } m_aEntries[NUM_MENUROWS]; }; +struct MenuTrapezoid +{ + float topLeft_x; + float topLeft_y; + float topRight_x; + float topRight_y; + float bottomLeft_x; + float bottomLeft_y; + float bottomRight_x; + float bottomRight_y; + float old_topRight_x; + float old_topRight_y; + float old_topLeft_x; + float old_topLeft_y; + float old_bottomLeft_x; + float old_bottomLeft_y; + float old_bottomRight_x; + float old_bottomRight_y; + float mult_topRight_x; + float mult_topRight_y; + float mult_topLeft_x; + float mult_topLeft_y; + float mult_bottomLeft_x; + float mult_bottomLeft_y; + float mult_bottomRight_x; + float mult_bottomRight_y; + + MenuTrapezoid(float x1, float y1, float x2, float y2, float x3, float y3, float x4, float y4) { + topLeft_x = x1; + topLeft_y = y1; + topRight_x = x2; + topRight_y = y2; + bottomLeft_x = x3; + bottomLeft_y = y3; + bottomRight_x = x4; + bottomRight_y = y4; + }; + + void SaveCurrentCoors() { + old_topLeft_x = topLeft_x; + old_topLeft_y = topLeft_y; + old_topRight_x = topRight_x; + old_topRight_y = topRight_y; + old_bottomLeft_x = bottomLeft_x; + old_bottomLeft_y = bottomLeft_y; + old_bottomRight_x = bottomRight_x; + old_bottomRight_y = bottomRight_y; + } + + void Translate(int delta) { + bottomRight_x = delta * mult_bottomRight_x + old_bottomRight_x; + bottomRight_y = delta * mult_bottomRight_y + old_bottomRight_y; + bottomLeft_x = delta * mult_bottomLeft_x + old_bottomLeft_x; + bottomLeft_y = delta * mult_bottomLeft_y + old_bottomLeft_y; + topRight_x = delta * mult_topRight_x + old_topRight_x; + topRight_y = delta * mult_topRight_y + old_topRight_y; + topLeft_x = delta * mult_topLeft_x + old_topLeft_x; + topLeft_y = delta * mult_topLeft_y + old_topLeft_y; + } + + void UpdateMultipliers() { + mult_bottomRight_x = (bottomRight_x - old_bottomRight_x) / 255.0f; + mult_bottomRight_y = (bottomRight_y - old_bottomRight_y) / 255.0f; + mult_bottomLeft_x = (bottomLeft_x - old_bottomLeft_x) / 255.0f; + mult_bottomLeft_y = (bottomLeft_y - old_bottomLeft_y) / 255.0f; + mult_topRight_x = (topRight_x - old_topRight_x) / 255.0f; + mult_topRight_y = (topRight_y - old_topRight_y) / 255.0f; + mult_topLeft_x = (topLeft_x - old_topLeft_x) / 255.0f; + mult_topLeft_y = (topLeft_y - old_topLeft_y) / 255.0f; + } +}; + class CMenuManager { public: - int32 m_nPrefsVideoMode; - int32 m_nDisplayVideoMode; + int8 m_StatsScrollDirection; + float m_StatsScrollSpeed; + uint8 field_8; + bool m_PrefsUseVibration; + bool m_PrefsShowHud; + int32 m_PrefsRadarMode; + uint8 field_10; + bool m_bShutDownFrontEndRequested; + bool m_bStartUpFrontEndRequested; + int32 m_KeyPressedCode; + int32 m_PrefsBrightness; + float m_PrefsLOD; + int8 m_PrefsShowSubtitles; + int8 m_PrefsShowLegends; + int8 m_PrefsUseWideScreen; + int8 m_PrefsVsync; // TODO(Miami): Are we sure? + int8 m_PrefsVsyncDisp; + int8 m_PrefsFrameLimiter; int8 m_nPrefsAudio3DProviderIndex; - bool m_bKeyChangeNotProcessed; - char m_aSkinName[256]; - int32 m_nHelperTextMsgId; - bool m_bLanguageLoaded; + int8 m_PrefsSpeakers; + int8 m_PrefsDMA; + uint8 m_PrefsSfxVolume; + uint8 m_PrefsMusicVolume; + uint8 m_PrefsRadioStation; + uint8 field_2C; + int32 m_nCurrOption; + bool m_bQuitGameNoCD; + bool m_bMenuMapActive; + bool m_AllowNavigation; + uint8 field_37; bool m_bMenuActive; - bool m_bMenuStateChanged; - bool m_bWaitingForNewKeyBind; bool m_bWantToRestart; bool m_bFirstTime; - bool m_bGameNotLoaded; - int32 m_nMousePosX; - int32 m_nMousePosY; + bool m_bActivateSaveMenu; + bool m_bWantToLoad; + float m_fMapSize; + float m_fMapCenterX; + float m_fMapCenterY; + uint32 OS_Language; + int32 m_PrefsLanguage; + int32 field_54; + int8 m_bLanguageLoaded; + uint8 m_PrefsAllowNastyGame; + uint8 m_PrefsMP3BoostVolume; + uint8 m_ControlMethod; + int32 m_nPrefsVideoMode; + int32 m_nDisplayVideoMode; int32 m_nMouseTempPosX; int32 m_nMouseTempPosY; + bool m_bGameNotLoaded; + int8 m_lastWorking3DAudioProvider; + bool m_bFrontEnd_ReloadObrTxtGxt; + int32 *pEditString; + uint8 field_74[4]; + int32 *pControlEdit; + bool m_OnlySaveMenu; + int32 m_menuTransitionProgress; + CSprite2d m_aFrontEndSprites[NUM_MENU_SPRITES]; + bool m_bSpritesLoaded; + int32 field_F0; + int32 m_LastRadioScrollDir; + int32 m_nCurrScreen; + int32 m_nPrevScreen; + int32 m_nCurrSaveSlot; + int32 m_LastScreenSwitch; + int32 m_nMenuFadeAlpha; + int32 bOptionHighlightTransitionBlend; + bool bMenuChangeOngoing; + int32 MouseButtonJustClicked; + int32 JoyButtonJustClicked; + bool DisplayComboButtonErrMsg; + bool m_NoEmptyBinding; + bool m_ShowEmptyBindingError; + int32 m_nHelperTextAlpha; + bool m_bPressedPgUpOnList; + bool m_bPressedPgDnOnList; + bool m_bPressedUpOnList; + bool m_bPressedDownOnList; + bool m_bPressedScrollButton; + uint8 field_129; + uint8 field_12A; + uint8 field_12B; + int32 m_nMousePosX; + int32 m_nMousePosY; + int32 m_nMouseOldPosX; + int32 m_nMouseOldPosY; + int32 m_nHoverOption; bool m_bShowMouse; + int32 m_nPrevOption; + bool m_bStartWaitingForKeyBind; + bool m_bWaitingForNewKeyBind; + bool m_bKeyChangeNotProcessed; + int32 m_CurrCntrlAction; + uint8 field_150; + uint8 field_151; + uint8 field_152; + uint8 field_153; + int32 m_nSelectedContSetupColumn; + bool m_bKeyIsOK; + bool field_159; + uint8 m_nCurrExLayer; + char m_PrefsSkinFile[256]; + char m_aSkinName[256]; + uint8 field_35B; + int32 m_nHelperTextMsgId; tSkinInfo m_pSkinListHead; tSkinInfo *m_pSelectedSkin; int32 m_nFirstVisibleRowOnList; float m_nScrollbarTopMargin; int32 m_nTotalListRow; int32 m_nSkinsTotal; - char _unk0[4]; + uint8 field_67C[4]; int32 m_nSelectedListRow; bool m_bSkinsEnumerated; - bool m_bQuitGameNoCD; - bool m_bRenderGameInMenu; - bool m_bSaveMenuActive; - bool m_bWantToLoad; - char field_455; - bool m_bStartWaitingForKeyBind; - bool m_bSpritesLoaded; - CSprite2d m_aFrontEndSprites[NUM_FE_SPRITES]; - CSprite2d m_aMenuSprites[NUM_MENU_SPRITES]; - int32 field_518; - int32 m_nMenuFadeAlpha; - bool m_bPressedPgUpOnList; - bool m_bPressedPgDnOnList; - bool m_bPressedUpOnList; - bool m_bPressedDownOnList; - bool m_bPressedScrollButton; - int32 m_CurrCntrlAction; - char _unk1[4]; - int32 m_nSelectedContSetupColumn; - bool m_bKeyIsOK; - bool field_535; - int8 m_nCurrExLayer; - int32 m_nHelperTextAlpha; - int32 m_nMouseOldPosX; - int32 m_nMouseOldPosY; - int32 m_nHoverOption; - int32 m_nCurrScreen; - int32 m_nCurrOption; - int32 m_nPrevOption; - int32 m_nPrevScreen; - uint32 field_558; - int32 m_nCurrSaveSlot; - int32 m_nScreenChangeDelayTimer; #ifdef IMPROVED_VIDEOMODE int32 m_nPrefsWidth; @@ -545,109 +630,66 @@ public: int32 m_nSelectedScreenMode; #endif -public: bool GetIsMenuActive() {return !!m_bMenuActive;} -public: - static int32 OS_Language; - static int8 m_PrefsUseVibration; - static int8 m_DisplayControllerOnFoot; - static int8 m_PrefsUseWideScreen; - static int8 m_PrefsRadioStation; - static int8 m_PrefsVsync; - static int8 m_PrefsVsyncDisp; - static int8 m_PrefsFrameLimiter; - static int8 m_PrefsShowSubtitles; - static int8 m_PrefsSpeakers; - static int32 m_ControlMethod; - static int8 m_PrefsDMA; - static int32 m_PrefsLanguage; - static int32 m_PrefsBrightness; - static float m_PrefsLOD; - static int8 m_bFrontEnd_ReloadObrTxtGxt; - static int32 m_PrefsMusicVolume; - static int32 m_PrefsSfxVolume; - static char m_PrefsSkinFile[256]; - static int32 m_KeyPressedCode; - - static bool m_bStartUpFrontEndRequested; - static bool m_bShutDownFrontEndRequested; - static bool m_PrefsAllowNastyGame; - static uint8 m_PrefsStereoMono; - static int32 m_SelectedMap; - static int32 m_SelectedGameType; - static uint8 m_PrefsPlayerRed; - static uint8 m_PrefsPlayerGreen; - static uint8 m_PrefsPlayerBlue; #ifndef MASTER static bool m_PrefsMarketing; static bool m_PrefsDisableTutorials; #endif // !MASTER -#ifdef MENU_MAP - static bool bMenuMapActive; - static bool bMapMouseShownOnce; - static bool bMapLoaded; - static float fMapSize; - static float fMapCenterY; - static float fMapCenterX; - static CSprite2d m_aMapSprites[NUM_MAP_SPRITES]; + CMenuManager(void); + ~CMenuManager(void) { UnloadTextures(); } + + void Initialise(); void PrintMap(); -#endif - -public: + void SetFrontEndRenderStates(); static void BuildStatLine(Const char *text, void *stat, bool itsFloat, void *stat2); static void CentreMousePointer(); void CheckCodesForControls(int); bool CheckHover(int x1, int x2, int y1, int y2); void CheckSliderMovement(int); - int CostructStatLine(int); void DisplayHelperText(); int DisplaySlider(float, float, float, float, float, float); void DoSettingsBeforeStartingAGame(); - void Draw(); + void DrawStandardMenus(); void DrawControllerBound(int32, int32, int32, int8); void DrawControllerScreenExtraText(int, int, int); void DrawControllerSetupScreen(); void DrawFrontEnd(); - void DrawFrontEndNormal(); -#ifdef PS2_SAVE_DIALOG - void DrawFrontEndSaveZone(); -#endif + void DrawBackground(bool transitionCall); void DrawPlayerSetupScreen(); int FadeIn(int alpha); void FilterOutColorMarkersFromString(wchar*, CRGBA &); int GetStartOptionsCntrlConfigScreens(); - static void InitialiseChangedLanguageSettings(); + void InitialiseChangedLanguageSettings(); void LoadAllTextures(); void LoadSettings(); void MessageScreen(const char *); // TODO(MIAMI): implement the second argument void MessageScreen(const char *str, bool) { MessageScreen(str); } - void PickNewPlayerColour(); void PrintBriefs(); static void PrintErrorMessage(); void PrintStats(); void Process(); void ProcessButtonPresses(); + void ProcessFileActions(); void ProcessOnOffMenuOptions(); - static void RequestFrontEndShutDown(); - static void RequestFrontEndStartUp(); + void RequestFrontEndShutDown(); + void RequestFrontEndStartUp(); void ResetHelperText(); void SaveLoadFileError_SetUpErrorScreen(); void SaveSettings(); void SetHelperText(int text); - void ShutdownJustMenu(); float StretchX(float); float StretchY(float); void SwitchMenuOnAndOff(); void UnloadTextures(); void WaitForUserCD(); - void PrintController(); int GetNumOptionsCntrlConfigScreens(); int ConstructStatLine(int); + void SwitchToNewScreen(int8); // New (not in function or inlined in the game) void ThingsToDoBeforeLeavingPage(); @@ -660,7 +702,7 @@ public: }; #ifndef IMPROVED_VIDEOMODE -VALIDATE_SIZE(CMenuManager, 0x564); +VALIDATE_SIZE(CMenuManager, 0x688); #endif extern CMenuManager FrontEndMenuManager; diff --git a/src/core/Game.cpp b/src/core/Game.cpp index b96c8988..72b09feb 100644 --- a/src/core/Game.cpp +++ b/src/core/Game.cpp @@ -64,6 +64,7 @@ #include "Script.h" #include "Shadows.h" #include "Skidmarks.h" +#include "SetPieces.h" #include "SpecialFX.h" #include "Sprite2d.h" #include "Stats.h" @@ -84,6 +85,7 @@ #include "World.h" #include "ZoneCull.h" #include "Zones.h" +#include "Occlusion.h" #include "debugmenu.h" @@ -220,20 +222,20 @@ bool CGame::InitialiseOnceAfterRW(void) if ( FrontEndMenuManager.m_nPrefsAudio3DProviderIndex == -99 || FrontEndMenuManager.m_nPrefsAudio3DProviderIndex == -2 ) { - CMenuManager::m_PrefsSpeakers = 0; + FrontEndMenuManager.m_PrefsSpeakers = 0; int8 provider = DMAudio.AutoDetect3DProviders(); if ( provider != -1 ) FrontEndMenuManager.m_nPrefsAudio3DProviderIndex = provider; } DMAudio.SetCurrent3DProvider(FrontEndMenuManager.m_nPrefsAudio3DProviderIndex); - DMAudio.SetSpeakerConfig(CMenuManager::m_PrefsSpeakers); - DMAudio.SetDynamicAcousticModelingStatus(CMenuManager::m_PrefsDMA); - DMAudio.SetMusicMasterVolume(CMenuManager::m_PrefsMusicVolume); - DMAudio.SetEffectsMasterVolume(CMenuManager::m_PrefsSfxVolume); + DMAudio.SetSpeakerConfig(FrontEndMenuManager.m_PrefsSpeakers); + DMAudio.SetDynamicAcousticModelingStatus(FrontEndMenuManager.m_PrefsDMA); + DMAudio.SetMusicMasterVolume(FrontEndMenuManager.m_PrefsMusicVolume); + DMAudio.SetEffectsMasterVolume(FrontEndMenuManager.m_PrefsSfxVolume); DMAudio.SetEffectsFadeVol(127); DMAudio.SetMusicFadeVol(127); - CWorld::Players[0].SetPlayerSkin(CMenuManager::m_PrefsSkinFile); + CWorld::Players[0].SetPlayerSkin(FrontEndMenuManager.m_PrefsSkinFile); return true; } @@ -272,7 +274,9 @@ bool CGame::Initialise(const char* datFile) ThePaths.AllocatePathFindInfoMem(4500); CWeather::Init(); CCullZones::Init(); + COcclusion::Init(); CCollision::Init(); + CSetPieces::Init(); CTheZones::Init(); CUserDisplay::Init(); CMessages::Init(); @@ -527,6 +531,7 @@ void CGame::ShutDownForRestart(void) CRadar::RemoveRadarSections(); FrontEndMenuManager.UnloadTextures(); CParticleObject::RemoveAllParticleObjects(); + CSetPieces::Init(); CPedType::Shutdown(); CSpecialFX::Shutdown(); TidyUpMemory(true, false); @@ -539,7 +544,14 @@ void CGame::InitialiseWhenRestarting(void) CTimer::Initialise(); CSprite2d::SetRecipNearClip(); - + + if (b_FoundRecentSavedGameWantToLoad || FrontEndMenuManager.m_bWantToLoad) + { + LoadSplash("splash1"); + if (FrontEndMenuManager.m_bWantToLoad) + FrontEndMenuManager.MessageScreen("FELD_WR", true); + } + b_FoundRecentSavedGameWantToLoad = false; TheCamera.Init(); @@ -620,6 +632,7 @@ void CGame::Process(void) CAntennas::Update(); CGlass::Update(); CSceneEdit::Update(); + CSetPieces::Update(); CEventList::Update(); CParticle::Update(); gFireManager.Update(); @@ -662,6 +675,16 @@ void CGame::Process(void) } } +void +CGame::InitAfterFocusLoss() +{ + FrontEndMenuManager.m_nPrefsAudio3DProviderIndex = FrontEndMenuManager.m_lastWorking3DAudioProvider; + DMAudio.SetCurrent3DProvider(FrontEndMenuManager.m_lastWorking3DAudioProvider); + + if (!FrontEndMenuManager.m_bGameNotLoaded && !FrontEndMenuManager.m_bMenuActive) + FrontEndMenuManager.m_bStartUpFrontEndRequested = true; +} + bool CGame::CanSeeOutSideFromCurrArea(void) { diff --git a/src/core/Game.h b/src/core/Game.h index 6efacf8d..7ad8d55e 100644 --- a/src/core/Game.h +++ b/src/core/Game.h @@ -59,6 +59,8 @@ public: static void InitialiseWhenRestarting(void); static void Process(void); + static void InitAfterFocusLoss(void); + static bool IsInInterior(void) { return currArea != AREA_MAIN_MAP; } static bool CanSeeOutSideFromCurrArea(void); diff --git a/src/core/MenuScreens.h b/src/core/MenuScreens.h index 6c2ebdb8..805a5aff 100644 --- a/src/core/MenuScreens.h +++ b/src/core/MenuScreens.h @@ -206,20 +206,12 @@ const CMenuScreen aScreens[] = { MENUACTION_MEMCARDSAVECONFIRM, "JAILB_U", SAVESLOT_NONE, MENUPAGE_NONE, }, - // Unused in PC but anyway // MENUPAGE_SAVE = 24 -#ifdef PS2_SAVE_DIALOG - { "FET_SG", 1, MENUPAGE_DISABLED, MENUPAGE_DISABLED, 0, 0, - MENUACTION_CHANGEMENU, "FESZ_SA", SAVESLOT_NONE, MENUPAGE_CHOOSE_SAVE_SLOT, - MENUACTION_RESUME_FROM_SAVEZONE, "FESZ_CA", SAVESLOT_NONE, MENUPAGE_NONE, - }, -#else { "FET_SG", 1, MENUPAGE_DISABLED, MENUPAGE_DISABLED, 0, 0, MENUACTION_LABEL, "FES_SCG", SAVESLOT_NONE, MENUPAGE_NONE, MENUACTION_POPULATESLOTS_CHANGEMENU, "GMSAVE", SAVESLOT_NONE, MENUPAGE_CHOOSE_SAVE_SLOT, MENUACTION_RESUME_FROM_SAVEZONE, "FESZ_CA", SAVESLOT_NONE, MENUPAGE_NONE, }, -#endif // MENUPAGE_NO_MEMORY_CARD_2 = 25 { "FES_NOC", 1, MENUPAGE_DISABLED, MENUPAGE_DISABLED, 0, 0, @@ -284,6 +276,9 @@ const CMenuScreen aScreens[] = { // MENUPAGE_CONTROLLER_PC = 35 { "FET_CTL", 1, MENUPAGE_OPTIONS, MENUPAGE_OPTIONS, 0, 0, MENUACTION_CTRLMETHOD, "FET_CME", SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC, +#ifdef FREE_CAM + MENUACTION_FREECAM, "FREECAM", SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC, +#endif MENUACTION_CHANGEMENU, "FET_RDK", SAVESLOT_NONE, MENUPAGE_KEYBOARD_CONTROLS, MENUACTION_CHANGEMENU, "FET_AMS", SAVESLOT_NONE, MENUPAGE_MOUSE_CONTROLS, MENUACTION_RESTOREDEF, "FET_DEF", SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC, diff --git a/src/core/Pad.cpp b/src/core/Pad.cpp index a40366ad..69f340dd 100644 --- a/src/core/Pad.cpp +++ b/src/core/Pad.cpp @@ -49,7 +49,7 @@ CKeyboardState CPad::OldKeyState; CKeyboardState CPad::NewKeyState; CKeyboardState CPad::TempKeyState; -char CPad::KeyBoardCheatString[20]; +char CPad::KeyBoardCheatString[30]; CMouseControllerState CPad::OldMouseControllerState; CMouseControllerState CPad::NewMouseControllerState; @@ -68,39 +68,39 @@ void WeaponCheat() CStreaming::RequestModel(MI_GRENADE, STREAMFLAGS_DONT_REMOVE); CStreaming::RequestModel(MI_BOMB, STREAMFLAGS_DONT_REMOVE); - CStreaming::RequestModel(MI_AK47, STREAMFLAGS_DONT_REMOVE); + CStreaming::RequestModel(MI_RUGER, STREAMFLAGS_DONT_REMOVE); CStreaming::RequestModel(MI_BASEBALL_BAT, STREAMFLAGS_DONT_REMOVE); - CStreaming::RequestModel(MI_COLT, STREAMFLAGS_DONT_REMOVE); + CStreaming::RequestModel(MI_COLT45, STREAMFLAGS_DONT_REMOVE); CStreaming::RequestModel(MI_ROCKETLAUNCHER, STREAMFLAGS_DONT_REMOVE); - CStreaming::RequestModel(MI_SHOTGUN, STREAMFLAGS_DONT_REMOVE); - CStreaming::RequestModel(MI_SNIPER, STREAMFLAGS_DONT_REMOVE); + CStreaming::RequestModel(MI_SPAS12_SHOTGUN, STREAMFLAGS_DONT_REMOVE); + CStreaming::RequestModel(MI_SNIPERRIFLE, STREAMFLAGS_DONT_REMOVE); CStreaming::RequestModel(MI_MP5, STREAMFLAGS_DONT_REMOVE); CStreaming::LoadAllRequestedModels(false); FindPlayerPed()->GiveWeapon(WEAPONTYPE_BASEBALLBAT, 0); FindPlayerPed()->GiveWeapon(WEAPONTYPE_COLT45, 100); FindPlayerPed()->GiveWeapon(WEAPONTYPE_MP5, 100); - FindPlayerPed()->GiveWeapon(WEAPONTYPE_SHOTGUN, 20); - FindPlayerPed()->GiveWeapon(WEAPONTYPE_AK47, 200); + FindPlayerPed()->GiveWeapon(WEAPONTYPE_SPAS12_SHOTGUN, 20); + FindPlayerPed()->GiveWeapon(WEAPONTYPE_RUGER, 200); FindPlayerPed()->GiveWeapon(WEAPONTYPE_SNIPERRIFLE, 5); FindPlayerPed()->GiveWeapon(WEAPONTYPE_ROCKETLAUNCHER, 5); FindPlayerPed()->GiveWeapon(WEAPONTYPE_DETONATOR_GRENADE, 5); CStreaming::SetModelIsDeletable(MI_GRENADE); CStreaming::SetModelIsDeletable(MI_BOMB); - CStreaming::SetModelIsDeletable(MI_AK47); + CStreaming::SetModelIsDeletable(MI_RUGER); CStreaming::SetModelIsDeletable(MI_BASEBALL_BAT); - CStreaming::SetModelIsDeletable(MI_COLT); + CStreaming::SetModelIsDeletable(MI_COLT45); CStreaming::SetModelIsDeletable(MI_ROCKETLAUNCHER); - CStreaming::SetModelIsDeletable(MI_SHOTGUN); - CStreaming::SetModelIsDeletable(MI_SNIPER); + CStreaming::SetModelIsDeletable(MI_SPAS12_SHOTGUN); + CStreaming::SetModelIsDeletable(MI_SNIPERRIFLE); CStreaming::SetModelIsDeletable(MI_MP5); } void HealthCheat() { CHud::SetHelpMessage(TheText.Get("CHEAT3"), true); - FindPlayerPed()->m_fHealth = 100.0f; + FindPlayerPed()->m_fHealth = CWorld::Players[0].m_nMaxHealth; if (FindPlayerVehicle()) { FindPlayerVehicle()->m_fHealth = 1000.0f; if (FindPlayerVehicle()->m_vehType == VEHICLE_TYPE_CAR) @@ -108,31 +108,31 @@ void HealthCheat() } } -void TankCheat() +void VehicleCheat(bool something, int model) { CHud::SetHelpMessage(TheText.Get("CHEAT1"), true); - CStreaming::RequestModel(MI_RHINO, 0); - CStreaming::LoadAllRequestedModels(false); - if (CStreaming::ms_aInfoForModel[MI_RHINO].m_loadState == STREAMSTATE_LOADED) { + CStreaming::RequestModel(model, 0); + CStreaming::LoadAllRequestedModels(something); + if (CStreaming::ms_aInfoForModel[model].m_loadState == STREAMSTATE_LOADED) { CHud::SetHelpMessage(TheText.Get("CHEAT1"), true); int32 node = ThePaths.FindNodeClosestToCoors(FindPlayerCoors(), PATH_CAR, 100.0f); if (node < 0) return; - + #ifdef FIX_BUGS - CAutomobile* tank = new CAutomobile(MI_RHINO, RANDOM_VEHICLE); + CAutomobile* vehicle = new CAutomobile(model, RANDOM_VEHICLE); #else - CAutomobile *tank = new CAutomobile(MI_RHINO, MISSION_VEHICLE); + CAutomobile* vehicle = new CAutomobile(MI_RHINO, MISSION_VEHICLE); #endif - if (tank != nil) { + if (vehicle != nil) { CVector pos = ThePaths.m_pathNodes[node].GetPosition(); pos.z += 4.0f; - tank->SetPosition(pos); - tank->SetOrientation(0.0f, 0.0f, DEGTORAD(200.0f)); + vehicle->SetPosition(pos); + vehicle->SetOrientation(0.0f, 0.0f, DEGTORAD(200.0f)); - tank->SetStatus(STATUS_ABANDONED); - tank->m_nDoorLock = CARLOCK_UNLOCKED; - CWorld::Add(tank); + vehicle->SetStatus(STATUS_ABANDONED); + vehicle->m_nDoorLock = CARLOCK_UNLOCKED; + CWorld::Add(vehicle); } } } @@ -224,7 +224,7 @@ void MoneyCheat() void ArmourCheat() { CHud::SetHelpMessage(TheText.Get("CHEAT4"), true); - FindPlayerPed()->m_fArmour = 100.0f; + FindPlayerPed()->m_fArmour = CWorld::Players[0].m_nMaxArmour; } void WantedLevelUpCheat() @@ -701,7 +701,7 @@ CControllerState CPad::ReconcileTwoControllersInput(CControllerState const &Stat void CPad::StartShake(int16 nDur, uint8 nFreq) { - if ( !CMenuManager::m_PrefsUseVibration ) + if ( !FrontEndMenuManager.m_PrefsUseVibration ) return; if ( CCutsceneMgr::IsRunning() || CGame::playingIntro ) @@ -723,7 +723,7 @@ void CPad::StartShake(int16 nDur, uint8 nFreq) void CPad::StartShake_Distance(int16 nDur, uint8 nFreq, float fX, float fY, float fZ) { - if ( !CMenuManager::m_PrefsUseVibration ) + if ( !FrontEndMenuManager.m_PrefsUseVibration ) return; if ( CCutsceneMgr::IsRunning() || CGame::playingIntro ) @@ -750,7 +750,7 @@ void CPad::StartShake_Distance(int16 nDur, uint8 nFreq, float fX, float fY, floa void CPad::StartShake_Train(float fX, float fY) { - if ( !CMenuManager::m_PrefsUseVibration ) + if ( !FrontEndMenuManager.m_PrefsUseVibration ) return; if ( CCutsceneMgr::IsRunning() || CGame::playingIntro ) @@ -824,7 +824,7 @@ void CPad::AddToCheatString(char c) // "CCCCCC321TCT" - CIRCLE CIRCLE CIRCLE CIRCLE CIRCLE CIRCLE R1 L2 L1 TRIANGLE CIRCLE TRIANGLE else if ( !_CHEATCMP("TCT123CCCCCC") ) - TankCheat(); + VehicleCheat(true, MI_RHINO); // "CCCSSSSS1TCT" - CIRCLE CIRCLE CIRCLE SQUARE SQUARE SQUARE SQUARE SQUARE L1 TRIANGLE CIRCLE TRIANGLE else if ( !_CHEATCMP("TCT1SSSSSCCC") ) @@ -905,10 +905,46 @@ void CPad::AddToPCCheatString(char c) // "NOPOLICEPLEASE" if ( !_CHEATCMP("ESAELPECILOPON") ) WantedLevelDownCheat(); - - // "GIVEUSATANK" - if ( !_CHEATCMP("KNATASUEVIG") ) - TankCheat(); + + // "PANZER" + if ( !_CHEATCMP("REZNAP") ) + VehicleCheat(true, MI_RHINO); + + // "TRAVELINSTYLE" + if ( !_CHEATCMP("ELYTSNILEVART") ) + VehicleCheat(true, MI_BLOODRA); + + // "GETTHEREQUICKLY" + if ( !_CHEATCMP("YLKCIUQEREHTTEG") ) + VehicleCheat(true, MI_BLOODRB); + + // "GETTHEREFAST" + if ( !_CHEATCMP("TSAFEREHTTEG") ) + VehicleCheat(true, MI_SABRETUR); + + // "GETTHEREVERYFASTINDEED" + if ( !_CHEATCMP("DEEDNITSAFYREVEREHTTEG") ) + VehicleCheat(true, MI_HOTRINA); + + // "GETTHEREAMAZINGLYFAST" + if ( !_CHEATCMP("TSAFYLGNIZAMAEREHTTEG") ) + VehicleCheat(true, MI_HOTRINB); + + // "THELASTRIDE" + if ( !_CHEATCMP("EDIRTSALEHT") ) + VehicleCheat(true, MI_ROMERO); + + // "ROCKANDROLLCAR" + if ( !_CHEATCMP("RACLLORDNAKCOR") ) + VehicleCheat(true, MI_LOVEFIST); + + // "RUBBISHCAR" + if ( !_CHEATCMP("RACHSIBBUR") ) + VehicleCheat(true, MI_TRASH); + + // "BETTERTHANWALKING" + if ( !_CHEATCMP("GNIKLAWNAHTRETTEB") ) + VehicleCheat(true, MI_CADDY); // "BANGBANGBANG" if ( !_CHEATCMP("GNABGNABGNAB") ) diff --git a/src/core/Pad.h b/src/core/Pad.h index ea771f81..ad93fb49 100644 --- a/src/core/Pad.h +++ b/src/core/Pad.h @@ -176,7 +176,7 @@ public: static CKeyboardState OldKeyState; static CKeyboardState NewKeyState; static CKeyboardState TempKeyState; - static char KeyBoardCheatString[20]; + static char KeyBoardCheatString[30]; static CMouseControllerState OldMouseControllerState; static CMouseControllerState NewMouseControllerState; static CMouseControllerState PCTempMouseControllerState; diff --git a/src/core/Placeable.cpp b/src/core/Placeable.cpp index 69b3d3ea..6efc1540 100644 --- a/src/core/Placeable.cpp +++ b/src/core/Placeable.cpp @@ -7,8 +7,6 @@ CPlaceable::CPlaceable(void) m_matrix.SetScale(1.0f); } -CPlaceable::~CPlaceable(void) = default; - void CPlaceable::SetHeading(float angle) { diff --git a/src/core/Placeable.h b/src/core/Placeable.h index 970c0d48..22f7583c 100644 --- a/src/core/Placeable.h +++ b/src/core/Placeable.h @@ -9,7 +9,6 @@ public: CMatrix m_matrix; CPlaceable(void); - virtual ~CPlaceable(void); const CVector &GetPosition(void) { return m_matrix.GetPosition(); } void SetPosition(float x, float y, float z) { m_matrix.GetPosition().x = x; diff --git a/src/core/PlayerInfo.cpp b/src/core/PlayerInfo.cpp index d7b3f0e5..675fafb3 100644 --- a/src/core/PlayerInfo.cpp +++ b/src/core/PlayerInfo.cpp @@ -140,20 +140,23 @@ CPlayerInfo::Clear(void) m_nUpsideDownCounter = 0; m_bInfiniteSprint = false; m_bFastReload = false; + m_nMaxHealth = m_nMaxArmour = 100; m_bGetOutOfJailFree = false; m_bGetOutOfHospitalFree = false; + m_bDriveByAllowed = true; m_nPreviousTimeRewardedForExplosion = 0; m_nExplosionsSinceLastReward = 0; } void -CPlayerInfo::BlowUpRCBuggy(void) +CPlayerInfo::BlowUpRCBuggy(bool actually) { if (!m_pRemoteVehicle || m_pRemoteVehicle->bRemoveFromWorld) return; CRemote::TakeRemoteControlledCarFromPlayer(); - m_pRemoteVehicle->BlowUpCar(FindPlayerPed()); + if (actually) + m_pRemoteVehicle->BlowUpCar(FindPlayerPed()); } void @@ -171,7 +174,6 @@ void CPlayerInfo::MakePlayerSafe(bool toggle) { if (toggle) { - CTheScripts::ResetCountdownToMakePlayerUnsafe(); m_pPed->m_pWanted->m_bIgnoredByEveryone = true; CWorld::StopAllLawEnforcersInTheirTracks(); CPad::GetPad(0)->DisablePlayerControls |= PLAYERCONTROL_DISABLED_20; @@ -192,7 +194,8 @@ CPlayerInfo::MakePlayerSafe(bool toggle) CWorld::ExtinguishAllCarFiresInArea(GetPos(), 4000.0f); CReplay::DisableReplays(); - } else if (!CGame::playingIntro && !CTheScripts::IsCountdownToMakePlayerUnsafeOn()) { + } + else { m_pPed->m_pWanted->m_bIgnoredByEveryone = false; CPad::GetPad(0)->DisablePlayerControls &= ~PLAYERCONTROL_DISABLED_20; m_pPed->bBulletProof = false; diff --git a/src/core/PlayerInfo.h b/src/core/PlayerInfo.h index c649d49d..e2e874e6 100644 --- a/src/core/PlayerInfo.h +++ b/src/core/PlayerInfo.h @@ -50,10 +50,16 @@ public: int32 m_nExplosionsSinceLastReward; int32 field_268; int32 field_272; + uint32 m_nHavocLevel; + float m_fMediaAttention; bool m_bInfiniteSprint; bool m_bFastReload; + bool m_bFireproof; + uint8 m_nMaxHealth; + uint8 m_nMaxArmour; bool m_bGetOutOfJailFree; bool m_bGetOutOfHospitalFree; + bool m_bDriveByAllowed; char m_aSkinName[32]; RwTexture *m_pSkinTexture; @@ -69,7 +75,7 @@ public: bool IsPlayerInRemoteMode(void); void PlayerFailedCriticalMission(void); void Clear(void); - void BlowUpRCBuggy(void); + void BlowUpRCBuggy(bool); void CancelPlayerEnteringCars(CVehicle*); bool IsRestartingAfterDeath(void); bool IsRestartingAfterArrest(void); diff --git a/src/core/Radar.cpp b/src/core/Radar.cpp index 5b0d38e8..475ca4d3 100644 --- a/src/core/Radar.cpp +++ b/src/core/Radar.cpp @@ -21,49 +21,87 @@ sRadarTrace CRadar::ms_RadarTrace[NUMRADARBLIPS]; CVector2D vec2DRadarOrigin; int32 gRadarTxdIds[64]; -CSprite2d CRadar::AsukaSprite; -CSprite2d CRadar::BombSprite; -CSprite2d CRadar::CatSprite; CSprite2d CRadar::CentreSprite; -CSprite2d CRadar::CopcarSprite; -CSprite2d CRadar::DonSprite; -CSprite2d CRadar::EightSprite; -CSprite2d CRadar::ElSprite; -CSprite2d CRadar::IceSprite; -CSprite2d CRadar::JoeySprite; -CSprite2d CRadar::KenjiSprite; -CSprite2d CRadar::LizSprite; -CSprite2d CRadar::LuigiSprite; +CSprite2d CRadar::MapHereSprite; CSprite2d CRadar::NorthSprite; -CSprite2d CRadar::RaySprite; -CSprite2d CRadar::SalSprite; -CSprite2d CRadar::SaveSprite; +CSprite2d CRadar::AverySprite; +CSprite2d CRadar::BikerSprite; +CSprite2d CRadar::CortezSprite; +CSprite2d CRadar::DiazSprite; +CSprite2d CRadar::KentSprite; +CSprite2d CRadar::LawyerSprite; +CSprite2d CRadar::PhilSprite; +CSprite2d CRadar::BikersSprite; +CSprite2d CRadar::BoatyardSprite; +CSprite2d CRadar::MalibuClubSprite; +CSprite2d CRadar::CubansSprite; +CSprite2d CRadar::FilmSprite; +CSprite2d CRadar::GunSprite; +CSprite2d CRadar::HaitiansSprite; +CSprite2d CRadar::HardwareSprite; +CSprite2d CRadar::SaveHouseSprite; +CSprite2d CRadar::StripSprite; +CSprite2d CRadar::IceSprite; +CSprite2d CRadar::KCabsSprite; +CSprite2d CRadar::LovefistSprite; +CSprite2d CRadar::PrintworksSprite; +CSprite2d CRadar::PropertySprite; +CSprite2d CRadar::SunYardSprite; CSprite2d CRadar::SpraySprite; -CSprite2d CRadar::TonySprite; -CSprite2d CRadar::WeaponSprite; +CSprite2d CRadar::TShirtSprite; +CSprite2d CRadar::TommySprite; +CSprite2d CRadar::PhoneSprite; +CSprite2d CRadar::RadioWildstyleSprite; +CSprite2d CRadar::RadioFlashSprite; +CSprite2d CRadar::RadioKChatSprite; +CSprite2d CRadar::RadioFeverSprite; +CSprite2d CRadar::RadioVRockSprite; +CSprite2d CRadar::RadioVCPRSprite; +CSprite2d CRadar::RadioEspantosoSprite; +CSprite2d CRadar::RadioEmotionSprite; +CSprite2d CRadar::RadioWaveSprite; CSprite2d *CRadar::RadarSprites[RADAR_SPRITE_COUNT] = { nil, - &AsukaSprite, - &BombSprite, - &CatSprite, &CentreSprite, - &CopcarSprite, - &DonSprite, - &EightSprite, - &ElSprite, - &IceSprite, - &JoeySprite, - &KenjiSprite, - &LizSprite, - &LuigiSprite, + &MapHereSprite, &NorthSprite, - &RaySprite, - &SalSprite, - &SaveSprite, + &AverySprite, + &BikerSprite, + &CortezSprite, + &DiazSprite, + &KentSprite, + &LawyerSprite, + &PhilSprite, + &BikersSprite, + &BoatyardSprite, + &MalibuClubSprite, + &CubansSprite, + &FilmSprite, + &GunSprite, + &HaitiansSprite, + &HardwareSprite, + &SaveHouseSprite, + &StripSprite, + &IceSprite, + &KCabsSprite, + &LovefistSprite, + &PrintworksSprite, + &PropertySprite, + &SunYardSprite, &SpraySprite, - &TonySprite, - &WeaponSprite + &TShirtSprite, + &TommySprite, + &PhoneSprite, + &RadioWildstyleSprite, + &RadioFlashSprite, + &RadioKChatSprite, + &RadioFeverSprite, + &RadioVRockSprite, + &RadioVCPRSprite, + &RadioEspantosoSprite, + &RadioEmotionSprite, + &RadioWaveSprite }; // Why this doesn't coincide with world coordinates i don't know @@ -87,12 +125,11 @@ static_assert(RADAR_TILE_SIZE == (RADAR_SIZE_Y / RADAR_NUM_TILES), "CRadar: not CRGBA CRadar::ArrowBlipColour1; CRGBA CRadar::ArrowBlipColour2; uint16 CRadar::MapLegendCounter; -uint16 CRadar::MapLegendList[NUM_MAP_LEGENDS]; +int16 CRadar::MapLegendList[NUM_MAP_LEGENDS]; int CRadar::TargetMarkerId = -1; CVector CRadar::TargetMarkerPos; #endif -// taken from VC float CRadar::cachedCos; float CRadar::cachedSin; @@ -227,7 +264,7 @@ int LineRadarBoxCollision(CVector2D &out, const CVector2D &p1, const CVector2D & uint8 CRadar::CalculateBlipAlpha(float dist) { #ifdef MENU_MAP - if (CMenuManager::bMenuMapActive) + if (FrontEndMenuManager.m_bMenuMapActive) return 255; #endif if (dist <= 1.0f) @@ -273,12 +310,9 @@ void CRadar::ClearBlip(int32 i) if (index != -1) { SetRadarMarkerState(index, false); ms_RadarTrace[index].m_bInUse = false; -#ifndef MENU_MAP - // Ssshhh ms_RadarTrace[index].m_eBlipType = BLIP_NONE; ms_RadarTrace[index].m_eBlipDisplay = BLIP_DISPLAY_NEITHER; ms_RadarTrace[index].m_eRadarSprite = RADAR_SPRITE_NONE; -#endif } } @@ -378,9 +412,8 @@ int CRadar::ClipRadarPoly(CVector2D *poly, const CVector2D *rect) bool CRadar::DisplayThisBlip(int32 counter) { switch (ms_RadarTrace[counter].m_eRadarSprite) { - case RADAR_SPRITE_BOMB: case RADAR_SPRITE_SPRAY: - case RADAR_SPRITE_WEAPON: + case RADAR_SPRITE_GUN: return true; default: return false; @@ -398,7 +431,7 @@ void CRadar::Draw3dMarkers() if (ms_RadarTrace[i].m_eBlipDisplay == BLIP_DISPLAY_BOTH || ms_RadarTrace[i].m_eBlipDisplay == BLIP_DISPLAY_MARKER_ONLY) { CVector pos = entity->GetPosition(); pos.z += 1.2f * CModelInfo::GetModelInfo(entity->GetModelIndex())->GetColModel()->boundingBox.max.z + 2.5f; - C3dMarkers::PlaceMarker(i | (ms_RadarTrace[i].m_BlipIndex << 16), 1, pos, 2.5f, 0, 128, 255, 255, 1024, 0.2f, 5); + C3dMarkers::PlaceMarker(i | (ms_RadarTrace[i].m_BlipIndex << 16), 1, pos, 2.5f, CARBLIP_MARKER_COLOR_R, CARBLIP_MARKER_COLOR_G, CARBLIP_MARKER_COLOR_B, CARBLIP_MARKER_COLOR_A, 1024, 0.2f, 5); } break; } @@ -412,7 +445,7 @@ void CRadar::Draw3dMarkers() if (ms_RadarTrace[i].m_eBlipDisplay == BLIP_DISPLAY_BOTH || ms_RadarTrace[i].m_eBlipDisplay == BLIP_DISPLAY_MARKER_ONLY) { CVector pos = entity->GetPosition(); pos.z += 3.0f; - C3dMarkers::PlaceMarker(i | (ms_RadarTrace[i].m_BlipIndex << 16), 1, pos, 1.5f, 0, 128, 255, 255, 1024, 0.2f, 5); + C3dMarkers::PlaceMarker(i | (ms_RadarTrace[i].m_BlipIndex << 16), 1, pos, 1.5f, CHARBLIP_MARKER_COLOR_R, CHARBLIP_MARKER_COLOR_G, CHARBLIP_MARKER_COLOR_B, CHARBLIP_MARKER_COLOR_A, 1024, 0.2f, 5); } break; } @@ -422,7 +455,7 @@ void CRadar::Draw3dMarkers() if (ms_RadarTrace[i].m_eBlipDisplay == BLIP_DISPLAY_BOTH || ms_RadarTrace[i].m_eBlipDisplay == BLIP_DISPLAY_MARKER_ONLY) { CVector pos = entity->GetPosition(); pos.z += CModelInfo::GetModelInfo(entity->GetModelIndex())->GetColModel()->boundingBox.max.z + 1.0f + 1.0f; - C3dMarkers::PlaceMarker(i | (ms_RadarTrace[i].m_BlipIndex << 16), 1, pos, 1.0f, 0, 128, 255, 255, 1024, 0.2f, 5); + C3dMarkers::PlaceMarker(i | (ms_RadarTrace[i].m_BlipIndex << 16), 1, pos, 1.0f, OBJECTBLIP_MARKER_COLOR_R, OBJECTBLIP_MARKER_COLOR_G, OBJECTBLIP_MARKER_COLOR_B, OBJECTBLIP_MARKER_COLOR_A, 1024, 0.2f, 5); } break; } @@ -431,7 +464,7 @@ void CRadar::Draw3dMarkers() case BLIP_CONTACT_POINT: if (!CTheScripts::IsPlayerOnAMission()) { if (ms_RadarTrace[i].m_eBlipDisplay == BLIP_DISPLAY_BOTH || ms_RadarTrace[i].m_eBlipDisplay == BLIP_DISPLAY_MARKER_ONLY) - C3dMarkers::PlaceMarkerSet(i | (ms_RadarTrace[i].m_BlipIndex << 16), 4, ms_RadarTrace[i].m_vecPos, 2.0f, 0, 128, 255, 128, 2048, 0.2f, 0); + C3dMarkers::PlaceMarkerSet(i | (ms_RadarTrace[i].m_BlipIndex << 16), 4, ms_RadarTrace[i].m_vecPos, 2.0f, COORDBLIP_MARKER_COLOR_R, COORDBLIP_MARKER_COLOR_G, COORDBLIP_MARKER_COLOR_B, COORDBLIP_MARKER_COLOR_A, 2048, 0.2f, 0); } break; } @@ -454,7 +487,7 @@ void CRadar::DrawBlips() TransformRadarPointToScreenSpace(out, in); #ifdef MENU_MAP - if (!CMenuManager::bMenuMapActive) { + if (!FrontEndMenuManager.m_bMenuMapActive) { #endif float angle; if (TheCamera.Cams[TheCamera.ActiveCam].Mode == CCam::MODE_TOPDOWN) @@ -481,11 +514,6 @@ void CRadar::DrawBlips() CEntity *blipEntity = nil; for(int blipId = 0; blipId < NUMRADARBLIPS; blipId++) { -#ifdef MENU_MAP - // A little hack to reuse cleared blips in menu map. hehe - if (!CMenuManager::bMenuMapActive || ms_RadarTrace[blipId].m_eBlipType == BLIP_CAR || - ms_RadarTrace[blipId].m_eBlipType == BLIP_CHAR || ms_RadarTrace[blipId].m_eBlipType == BLIP_OBJECT) -#endif if (!ms_RadarTrace[blipId].m_bInUse) continue; @@ -493,8 +521,8 @@ void CRadar::DrawBlips() case BLIP_CAR: case BLIP_CHAR: case BLIP_OBJECT: - if (ms_RadarTrace[blipId].m_eRadarSprite == RADAR_SPRITE_BOMB || ms_RadarTrace[blipId].m_eRadarSprite == RADAR_SPRITE_SAVE - || ms_RadarTrace[blipId].m_eRadarSprite == RADAR_SPRITE_SPRAY || ms_RadarTrace[blipId].m_eRadarSprite == RADAR_SPRITE_WEAPON) { + if (ms_RadarTrace[blipId].m_eRadarSprite == RADAR_SPRITE_SAVE + || ms_RadarTrace[blipId].m_eRadarSprite == RADAR_SPRITE_SPRAY || ms_RadarTrace[blipId].m_eRadarSprite == RADAR_SPRITE_GUN) { switch (ms_RadarTrace[blipId].m_eBlipType) { case BLIP_CAR: @@ -527,7 +555,7 @@ void CRadar::DrawBlips() TransformRealWorldPointToRadarSpace(in, blipEntity->GetPosition()); float dist = LimitRadarPoint(in); TransformRadarPointToScreenSpace(out, in); - if (!ms_RadarTrace[blipId].m_bShortRange || dist <= 1.0f || CMenuManager::bMenuMapActive) { + if (!ms_RadarTrace[blipId].m_bShortRange || dist <= 1.0f || FrontEndMenuManager.m_bMenuMapActive) { if (ms_RadarTrace[blipId].m_eRadarSprite != RADAR_SPRITE_NONE) { DrawRadarSprite(ms_RadarTrace[blipId].m_eRadarSprite, out.x, out.y, CalculateBlipAlpha(dist)); } @@ -552,8 +580,8 @@ void CRadar::DrawBlips() break; case BLIP_COORD: case BLIP_CONTACT_POINT: - if ((ms_RadarTrace[blipId].m_eRadarSprite == RADAR_SPRITE_BOMB || ms_RadarTrace[blipId].m_eRadarSprite == RADAR_SPRITE_SAVE - || ms_RadarTrace[blipId].m_eRadarSprite == RADAR_SPRITE_SPRAY || ms_RadarTrace[blipId].m_eRadarSprite == RADAR_SPRITE_WEAPON) + if ((ms_RadarTrace[blipId].m_eRadarSprite == RADAR_SPRITE_SAVE + || ms_RadarTrace[blipId].m_eRadarSprite == RADAR_SPRITE_SPRAY || ms_RadarTrace[blipId].m_eRadarSprite == RADAR_SPRITE_GUN) && (ms_RadarTrace[blipId].m_eBlipType != BLIP_CONTACT_POINT || !CTheScripts::IsPlayerOnAMission())) { uint32 color = GetRadarTraceColour(ms_RadarTrace[blipId].m_nColor, ms_RadarTrace[blipId].m_bDim); @@ -569,7 +597,7 @@ void CRadar::DrawBlips() TransformRealWorldPointToRadarSpace(in, ms_RadarTrace[blipId].m_vec2DPos); float dist = LimitRadarPoint(in); TransformRadarPointToScreenSpace(out, in); - if (!ms_RadarTrace[blipId].m_bShortRange || dist <= 1.0f || CMenuManager::bMenuMapActive) { + if (!ms_RadarTrace[blipId].m_bShortRange || dist <= 1.0f || FrontEndMenuManager.m_bMenuMapActive) { if (ms_RadarTrace[blipId].m_eRadarSprite != RADAR_SPRITE_NONE) { DrawRadarSprite(ms_RadarTrace[blipId].m_eRadarSprite, out.x, out.y, CalculateBlipAlpha(dist)); } @@ -603,8 +631,8 @@ void CRadar::DrawBlips() case BLIP_CAR: case BLIP_CHAR: case BLIP_OBJECT: - if (ms_RadarTrace[blipId].m_eRadarSprite != RADAR_SPRITE_BOMB && ms_RadarTrace[blipId].m_eRadarSprite != RADAR_SPRITE_SAVE - && ms_RadarTrace[blipId].m_eRadarSprite != RADAR_SPRITE_SPRAY && ms_RadarTrace[blipId].m_eRadarSprite != RADAR_SPRITE_WEAPON) { + if (ms_RadarTrace[blipId].m_eRadarSprite != RADAR_SPRITE_SAVE + && ms_RadarTrace[blipId].m_eRadarSprite != RADAR_SPRITE_SPRAY && ms_RadarTrace[blipId].m_eRadarSprite != RADAR_SPRITE_GUN) { switch (ms_RadarTrace[blipId].m_eBlipType) { case BLIP_CAR: @@ -638,7 +666,7 @@ void CRadar::DrawBlips() TransformRealWorldPointToRadarSpace(in, blipEntity->GetPosition()); float dist = LimitRadarPoint(in); TransformRadarPointToScreenSpace(out, in); - if (!ms_RadarTrace[blipId].m_bShortRange || dist <= 1.0f || CMenuManager::bMenuMapActive) { + if (!ms_RadarTrace[blipId].m_bShortRange || dist <= 1.0f || FrontEndMenuManager.m_bMenuMapActive) { if (ms_RadarTrace[blipId].m_eRadarSprite != RADAR_SPRITE_NONE) DrawRadarSprite(ms_RadarTrace[blipId].m_eRadarSprite, out.x, out.y, CalculateBlipAlpha(dist)); else @@ -672,8 +700,8 @@ void CRadar::DrawBlips() switch (ms_RadarTrace[blipId].m_eBlipType) { case BLIP_COORD: case BLIP_CONTACT_POINT: - if (ms_RadarTrace[blipId].m_eRadarSprite != RADAR_SPRITE_BOMB && ms_RadarTrace[blipId].m_eRadarSprite != RADAR_SPRITE_SAVE - && ms_RadarTrace[blipId].m_eRadarSprite != RADAR_SPRITE_SPRAY && ms_RadarTrace[blipId].m_eRadarSprite != RADAR_SPRITE_WEAPON + if (ms_RadarTrace[blipId].m_eRadarSprite != RADAR_SPRITE_SAVE + && ms_RadarTrace[blipId].m_eRadarSprite != RADAR_SPRITE_SPRAY && ms_RadarTrace[blipId].m_eRadarSprite != RADAR_SPRITE_GUN && (ms_RadarTrace[blipId].m_eBlipType != BLIP_CONTACT_POINT || !CTheScripts::IsPlayerOnAMission())) { uint32 color = GetRadarTraceColour(ms_RadarTrace[blipId].m_nColor, ms_RadarTrace[blipId].m_bDim); @@ -689,7 +717,7 @@ void CRadar::DrawBlips() TransformRealWorldPointToRadarSpace(in, ms_RadarTrace[blipId].m_vec2DPos); float dist = LimitRadarPoint(in); TransformRadarPointToScreenSpace(out, in); - if (!ms_RadarTrace[blipId].m_bShortRange || dist <= 1.0f || CMenuManager::bMenuMapActive) { + if (!ms_RadarTrace[blipId].m_bShortRange || dist <= 1.0f || FrontEndMenuManager.m_bMenuMapActive) { if (ms_RadarTrace[blipId].m_eRadarSprite != RADAR_SPRITE_NONE) DrawRadarSprite(ms_RadarTrace[blipId].m_eRadarSprite, out.x, out.y, CalculateBlipAlpha(dist)); else @@ -716,7 +744,7 @@ void CRadar::DrawBlips() } } #ifdef MENU_MAP - if (CMenuManager::bMenuMapActive) { + if (FrontEndMenuManager.m_bMenuMapActive) { CVector2D in, out; TransformRealWorldPointToRadarSpace(in, FindPlayerCentreOfWorld_NoSniperShift()); TransformRadarPointToScreenSpace(out, in); @@ -871,7 +899,7 @@ void CRadar::DrawRadarSprite(uint16 sprite, float x, float y, uint8 alpha) { RadarSprites[sprite]->Draw(CRect(x - SCREEN_SCALE_X(8.0f), y - SCREEN_SCALE_Y(8.0f), x + SCREEN_SCALE_X(8.0f), y + SCREEN_SCALE_Y(8.0f)), CRGBA(255, 255, 255, alpha)); #ifdef MENU_MAP - if (CMenuManager::bMenuMapActive) { + if (FrontEndMenuManager.m_bMenuMapActive) { bool alreadyThere = false; for (int i = 0; i < NUM_MAP_LEGENDS; i++) { if (MapLegendList[i] == sprite) @@ -1019,7 +1047,7 @@ float CRadar::LimitRadarPoint(CVector2D &point) dist = point.Magnitude(); #ifdef MENU_MAP - if (CMenuManager::bMenuMapActive) + if (FrontEndMenuManager.m_bMenuMapActive) return dist; #endif if (dist > 1.0f) { @@ -1047,26 +1075,45 @@ CRadar::LoadTextures() { CTxdStore::PushCurrentTxd(); CTxdStore::SetCurrentTxd(CTxdStore::FindTxdSlot("hud")); - AsukaSprite.SetTexture("radar_asuka"); - BombSprite.SetTexture("radar_bomb"); - CatSprite.SetTexture("radar_cat"); CentreSprite.SetTexture("radar_centre"); - CopcarSprite.SetTexture("radar_copcar"); - DonSprite.SetTexture("radar_don"); - EightSprite.SetTexture("radar_eight"); - ElSprite.SetTexture("radar_el"); - IceSprite.SetTexture("radar_ice"); - JoeySprite.SetTexture("radar_joey"); - KenjiSprite.SetTexture("radar_kenji"); - LizSprite.SetTexture("radar_liz"); - LuigiSprite.SetTexture("radar_luigi"); + MapHereSprite.SetTexture("arrow"); NorthSprite.SetTexture("radar_north"); - RaySprite.SetTexture("radar_ray"); - SalSprite.SetTexture("radar_sal"); - SaveSprite.SetTexture("radar_save"); - SpraySprite.SetTexture("radar_spray"); - TonySprite.SetTexture("radar_tony"); - WeaponSprite.SetTexture("radar_weapon"); + AverySprite.SetTexture("radar_avery"); + BikerSprite.SetTexture("radar_biker"); + CortezSprite.SetTexture("radar_cortez"); + DiazSprite.SetTexture("radar_diaz"); + KentSprite.SetTexture("radar_kent"); + LawyerSprite.SetTexture("radar_lawyer"); + PhilSprite.SetTexture("radar_phil"); + BikersSprite.SetTexture("bikers"); + BoatyardSprite.SetTexture("boatyard"); + MalibuClubSprite.SetTexture("club"); + CubansSprite.SetTexture("cubans"); + FilmSprite.SetTexture("filmstudio"); + GunSprite.SetTexture("gun"); + HaitiansSprite.SetTexture("haitians"); + HardwareSprite.SetTexture("hardware"); + SaveHouseSprite.SetTexture("radar_save"); + StripSprite.SetTexture("radar_strip"); + IceSprite.SetTexture("icecream"); + KCabsSprite.SetTexture("kcabs"); + LovefistSprite.SetTexture("lovefist"); + PrintworksSprite.SetTexture("printworks"); + PropertySprite.SetTexture("property"); + SunYardSprite.SetTexture("SunYard"); + SpraySprite.SetTexture("spray"); + TShirtSprite.SetTexture("tshirt"); + TommySprite.SetTexture("tommy"); + PhoneSprite.SetTexture("phone"); + RadioWildstyleSprite.SetTexture("RWildstyle"); + RadioFlashSprite.SetTexture("RFlash"); + RadioKChatSprite.SetTexture("RKchat"); + RadioFeverSprite.SetTexture("RFever"); + RadioVRockSprite.SetTexture("RVRock"); + RadioVCPRSprite.SetTexture("RVCPR"); + RadioEspantosoSprite.SetTexture("REspantoso"); + RadioEmotionSprite.SetTexture("REmotion"); + RadioWaveSprite.SetTexture("RWave"); CTxdStore::PopCurrentTxd(); } @@ -1231,7 +1278,7 @@ void CRadar::ShowRadarTraceWithHeight(float x, float y, uint32 size, uint8 red, } #ifdef MENU_MAP // VC uses -1 for coords and -2 for entities but meh, I don't want to edit DrawBlips - if (CMenuManager::bMenuMapActive) { + if (FrontEndMenuManager.m_bMenuMapActive) { bool alreadyThere = false; for (int i = 0; i < NUM_MAP_LEGENDS; i++) { if (MapLegendList[i] == -1) @@ -1248,26 +1295,45 @@ void CRadar::ShowRadarTraceWithHeight(float x, float y, uint32 size, uint8 red, void CRadar::Shutdown() { - AsukaSprite.Delete(); - BombSprite.Delete(); - CatSprite.Delete(); CentreSprite.Delete(); - CopcarSprite.Delete(); - DonSprite.Delete(); - EightSprite.Delete(); - ElSprite.Delete(); - IceSprite.Delete(); - JoeySprite.Delete(); - KenjiSprite.Delete(); - LizSprite.Delete(); - LuigiSprite.Delete(); + MapHereSprite.Delete(); NorthSprite.Delete(); - RaySprite.Delete(); - SalSprite.Delete(); - SaveSprite.Delete(); + AverySprite.Delete(); + BikerSprite.Delete(); + CortezSprite.Delete(); + DiazSprite.Delete(); + KentSprite.Delete(); + LawyerSprite.Delete(); + PhilSprite.Delete(); + BikersSprite.Delete(); + BoatyardSprite.Delete(); + MalibuClubSprite.Delete(); + CubansSprite.Delete(); + FilmSprite.Delete(); + GunSprite.Delete(); + HaitiansSprite.Delete(); + HardwareSprite.Delete(); + SaveHouseSprite.Delete(); + StripSprite.Delete(); + IceSprite.Delete(); + KCabsSprite.Delete(); + LovefistSprite.Delete(); + PrintworksSprite.Delete(); + PropertySprite.Delete(); + SunYardSprite.Delete(); SpraySprite.Delete(); - TonySprite.Delete(); - WeaponSprite.Delete(); + TShirtSprite.Delete(); + TommySprite.Delete(); + PhoneSprite.Delete(); + RadioWildstyleSprite.Delete(); + RadioFlashSprite.Delete(); + RadioKChatSprite.Delete(); + RadioFeverSprite.Delete(); + RadioVRockSprite.Delete(); + RadioVCPRSprite.Delete(); + RadioEspantosoSprite.Delete(); + RadioEmotionSprite.Delete(); + RadioWaveSprite.Delete(); RemoveRadarSections(); } @@ -1337,10 +1403,9 @@ void CRadar::TransformRadarPointToRealWorldSpace(CVector2D &out, const CVector2D void CRadar::TransformRadarPointToScreenSpace(CVector2D &out, const CVector2D &in) { #ifdef MENU_MAP - if (CMenuManager::bMenuMapActive) { - // fMapSize is actually half map size. Radar range is 1000, so if x is -2000, in.x + 2.0f is 0. - out.x = (CMenuManager::fMapCenterX - CMenuManager::fMapSize) + (in.x + 2.0f) * CMenuManager::fMapSize * 2.0f / 4.0f; - out.y = (CMenuManager::fMapCenterY - CMenuManager::fMapSize) + (2.0f - in.y) * CMenuManager::fMapSize * 2.0f / 4.0f; + if (FrontEndMenuManager.m_bMenuMapActive) { + out.x = (FrontEndMenuManager.m_fMapCenterX - FrontEndMenuManager.m_fMapSize) + (MENU_MAP_LENGTH / 2 + MENU_MAP_LEFT_OFFSET + in.x) * FrontEndMenuManager.m_fMapSize * MENU_MAP_WIDTH_SCALE * 2.0f / MENU_MAP_LENGTH; + out.y = (FrontEndMenuManager.m_fMapCenterY - FrontEndMenuManager.m_fMapSize) + (MENU_MAP_LENGTH / 2 - MENU_MAP_TOP_OFFSET - in.y) * FrontEndMenuManager.m_fMapSize * MENU_MAP_HEIGHT_SCALE * 2.0f / MENU_MAP_LENGTH; } else #endif { @@ -1398,7 +1463,7 @@ CRadar::CalculateCachedSinCos() { if (TheCamera.Cams[TheCamera.ActiveCam].Mode == CCam::MODE_TOPDOWN || TheCamera.Cams[TheCamera.ActiveCam].Mode == CCam::MODE_TOP_DOWN_PED #ifdef MENU_MAP - || CMenuManager::bMenuMapActive + || FrontEndMenuManager.m_bMenuMapActive #endif ) { cachedSin = 0.0f; @@ -1428,7 +1493,7 @@ CRadar::InitFrontEndMap() CalculateCachedSinCos(); vec2DRadarOrigin.x = 0.0f; vec2DRadarOrigin.y = 0.0f; - m_radarRange = 1000.0f; // doesn't mean anything, just affects the calculation in TransformRadarPointToScreenSpace + m_radarRange = MENU_MAP_LENGTH_UNIT; // just affects the multiplier in TransformRadarPointToScreenSpace for (int i = 0; i < NUM_MAP_LEGENDS; i++) { MapLegendList[i] = RADAR_SPRITE_NONE; } diff --git a/src/core/Radar.h b/src/core/Radar.h index 43c9766a..61d94d05 100644 --- a/src/core/Radar.h +++ b/src/core/Radar.h @@ -1,6 +1,33 @@ #pragma once #include "Sprite2d.h" +#define CARBLIP_MARKER_COLOR_R 252 +#define CARBLIP_MARKER_COLOR_G 138 +#define CARBLIP_MARKER_COLOR_B 242 +#define CARBLIP_MARKER_COLOR_A 255 + +#define CHARBLIP_MARKER_COLOR_R 252 +#define CHARBLIP_MARKER_COLOR_G 138 +#define CHARBLIP_MARKER_COLOR_B 242 +#define CHARBLIP_MARKER_COLOR_A 255 + +#define OBJECTBLIP_MARKER_COLOR_R 252 +#define OBJECTBLIP_MARKER_COLOR_G 138 +#define OBJECTBLIP_MARKER_COLOR_B 242 +#define OBJECTBLIP_MARKER_COLOR_A 255 + +#define COORDBLIP_MARKER_COLOR_R 252 +#define COORDBLIP_MARKER_COLOR_G 138 +#define COORDBLIP_MARKER_COLOR_B 242 +#define COORDBLIP_MARKER_COLOR_A 255 + +#define MENU_MAP_LENGTH_UNIT 1190.0f // in game unit +#define MENU_MAP_WIDTH_SCALE 1.112f // in game unit (originally 1.112494151260504f) +#define MENU_MAP_HEIGHT_SCALE 1.119f // in game unit (originally 1.118714268907563f) +#define MENU_MAP_TOP_OFFSET 0.28f // in length unit defined above - ~333 game unit +#define MENU_MAP_LEFT_OFFSET 0.185f // in length unit defined above - ~220 game unit +#define MENU_MAP_LENGTH (4000.f / MENU_MAP_LENGTH_UNIT) + enum eBlipType { BLIP_NONE, @@ -26,27 +53,47 @@ enum eRadarSprite RADAR_SPRITE_COORD_BLIP = -1, #endif RADAR_SPRITE_NONE = 0, - RADAR_SPRITE_ASUKA = 1, - RADAR_SPRITE_BOMB = 2, - RADAR_SPRITE_CAT = 3, - RADAR_SPRITE_CENTRE = 4, - RADAR_SPRITE_COPCAR = 5, - RADAR_SPRITE_DON = 6, - RADAR_SPRITE_EIGHT = 7, - RADAR_SPRITE_EL = 8, - RADAR_SPRITE_ICE = 9, - RADAR_SPRITE_JOEY = 10, - RADAR_SPRITE_KENJI = 11, - RADAR_SPRITE_LIZ = 12, - RADAR_SPRITE_LUIGI = 13, - RADAR_SPRITE_NORTH = 14, - RADAR_SPRITE_RAY = 15, - RADAR_SPRITE_SAL = 16, - RADAR_SPRITE_SAVE = 17, - RADAR_SPRITE_SPRAY = 18, - RADAR_SPRITE_TONY = 19, - RADAR_SPRITE_WEAPON = 20, - RADAR_SPRITE_COUNT = 21, + RADAR_SPRITE_CENTRE, + RADAR_SPRITE_MAP_HERE, + RADAR_SPRITE_NORTH, + RADAR_SPRITE_AVERY, + RADAR_SPRITE_BIKER, + RADAR_SPRITE_CORTEZ, + RADAR_SPRITE_DIAZ, + RADAR_SPRITE_KENT, + RADAR_SPRITE_LAWYER, + RADAR_SPRITE_PHIL, + RADAR_SPRITE_BIKERS, + RADAR_SPRITE_BOATYARD, + RADAR_SPRITE_MALIBU_CLUB, + RADAR_SPRITE_CUBANS, + RADAR_SPRITE_FILM, + RADAR_SPRITE_GUN, + RADAR_SPRITE_HAITIANS, + RADAR_SPRITE_HARDWARE, + RADAR_SPRITE_SAVE, + RADAR_SPRITE_STRIP, + RADAR_SPRITE_ICE, + RADAR_SPRITE_KCABS, + RADAR_SPRITE_LOVEFIST, + RADAR_SPRITE_PRINTWORKS, + RADAR_SPRITE_PROPERTY, + RADAR_SPRITE_SUNYARD, + RADAR_SPRITE_SPRAY, + RADAR_SPRITE_TSHIRT, + RADAR_SPRITE_TOMMY, + RADAR_SPRITE_PHONE, + RADAR_SPRITE_RADIO_WILDSTYLE, + RADAR_SPRITE_RADIO_FLASH, + RADAR_SPRITE_RADIO_KCHAT, + RADAR_SPRITE_RADIO_FEVER, + RADAR_SPRITE_RADIO_VROCK, + RADAR_SPRITE_RADIO_VCPR, + RADAR_SPRITE_RADIO_ESPANTOSO, + RADAR_SPRITE_RADIO_EMOTION, + RADAR_SPRITE_RADIO_WAVE, + + RADAR_SPRITE_COUNT }; enum @@ -84,34 +131,53 @@ class CRadar public: static float m_radarRange; static sRadarTrace ms_RadarTrace[NUMRADARBLIPS]; - static CSprite2d AsukaSprite; - static CSprite2d BombSprite; - static CSprite2d CatSprite; static CSprite2d CentreSprite; - static CSprite2d CopcarSprite; - static CSprite2d DonSprite; - static CSprite2d EightSprite; - static CSprite2d ElSprite; - static CSprite2d IceSprite; - static CSprite2d JoeySprite; - static CSprite2d KenjiSprite; - static CSprite2d LizSprite; - static CSprite2d LuigiSprite; + static CSprite2d MapHereSprite; static CSprite2d NorthSprite; - static CSprite2d RaySprite; - static CSprite2d SalSprite; - static CSprite2d SaveSprite; + static CSprite2d AverySprite; + static CSprite2d BikerSprite; + static CSprite2d CortezSprite; + static CSprite2d DiazSprite; + static CSprite2d KentSprite; + static CSprite2d LawyerSprite; + static CSprite2d PhilSprite; + static CSprite2d BikersSprite; + static CSprite2d BoatyardSprite; + static CSprite2d MalibuClubSprite; + static CSprite2d CubansSprite; + static CSprite2d FilmSprite; + static CSprite2d GunSprite; + static CSprite2d HaitiansSprite; + static CSprite2d HardwareSprite; + static CSprite2d SaveHouseSprite; + static CSprite2d StripSprite; + static CSprite2d IceSprite; + static CSprite2d KCabsSprite; + static CSprite2d LovefistSprite; + static CSprite2d PrintworksSprite; + static CSprite2d PropertySprite; + static CSprite2d SunYardSprite; static CSprite2d SpraySprite; - static CSprite2d TonySprite; - static CSprite2d WeaponSprite; - static CSprite2d *RadarSprites[21]; + static CSprite2d TShirtSprite; + static CSprite2d TommySprite; + static CSprite2d PhoneSprite; + static CSprite2d RadioWildstyleSprite; + static CSprite2d RadioFlashSprite; + static CSprite2d RadioKChatSprite; + static CSprite2d RadioFeverSprite; + static CSprite2d RadioVRockSprite; + static CSprite2d RadioVCPRSprite; + static CSprite2d RadioEspantosoSprite; + static CSprite2d RadioEmotionSprite; + static CSprite2d RadioWaveSprite; + static CSprite2d *RadarSprites[RADAR_SPRITE_COUNT]; static float cachedCos; static float cachedSin; #ifdef MENU_MAP #define NUM_MAP_LEGENDS 75 static CRGBA ArrowBlipColour1; static CRGBA ArrowBlipColour2; - static uint16 MapLegendList[NUM_MAP_LEGENDS]; + static int16 MapLegendList[NUM_MAP_LEGENDS]; static uint16 MapLegendCounter; static int TargetMarkerId; static CVector TargetMarkerPos; diff --git a/src/core/Stats.cpp b/src/core/Stats.cpp index ea934dca..3f930d49 100644 --- a/src/core/Stats.cpp +++ b/src/core/Stats.cpp @@ -57,9 +57,13 @@ int32 CStats::mmRain; int32 CStats::CarsCrushed; int32 CStats::FastestTimes[CStats::TOTAL_FASTEST_TIMES]; int32 CStats::HighestScores[CStats::TOTAL_HIGHEST_SCORES]; +int32 CStats::PropertyDestroyed; int32 CStats::Sprayings; float CStats::AutoPaintingBudget; +int32 CStats::NoMoreHurricanes; +float CStats::FashionBudget; +int32 CStats::SafeHouseVisits; void CStats::Init() { @@ -119,6 +123,8 @@ void CStats::Init() Sprayings = 0; AutoPaintingBudget = 0.0f; + NoMoreHurricanes = 0; + SafeHouseVisits = 0; } void CStats::RegisterFastestTime(int32 index, int32 time) @@ -247,6 +253,19 @@ int32 CStats::FindCriminalRatingNumber() return rating; } +float CStats::GetPercentageProgress() +{ + float percentCompleted = (CStats::TotalProgressInGame == 0 ? 0 : + CStats::ProgressMade * 100.0f / (CGame::nastyGame ? CStats::TotalProgressInGame : CStats::TotalProgressInGame - 1.0f)); + + return Min(percentCompleted, 100.0f); +} + +void CStats::MoneySpentOnFashion(int32 money) +{ + FashionBudget += money; +} + void CStats::SaveStats(uint8 *buf, uint32 *size) { CheckPointReachedSuccessfully(); diff --git a/src/core/Stats.h b/src/core/Stats.h index 51f1d091..37987ae5 100644 --- a/src/core/Stats.h +++ b/src/core/Stats.h @@ -10,7 +10,7 @@ public: TOTAL_HIGHEST_SCORES = 16 }; static int32 DaysPassed; - static int32 HeadsPopped; + static int32 HeadsPopped; static int32 CommercialPassed; static int32 IndustrialPassed; static int32 SuburbanPassed; @@ -52,18 +52,22 @@ public: static int32 LongestFlightInDodo; static int32 TimeTakenDefuseMission; static int32 TotalNumberKillFrenzies; - static int32 TotalNumberMissions; - static int32 RoundsFiredByPlayer; - static int32 KgsOfExplosivesUsed; - static int32 InstantHitsFiredByPlayer; - static int32 InstantHitsHitByPlayer; - static int32 BestTimeBombDefusal; - static int32 mmRain; - static int32 CarsCrushed; + static int32 TotalNumberMissions; + static int32 RoundsFiredByPlayer; + static int32 KgsOfExplosivesUsed; + static int32 InstantHitsFiredByPlayer; + static int32 InstantHitsHitByPlayer; + static int32 BestTimeBombDefusal; + static int32 mmRain; + static int32 CarsCrushed; static int32 FastestTimes[TOTAL_FASTEST_TIMES]; static int32 HighestScores[TOTAL_HIGHEST_SCORES]; + static int32 PropertyDestroyed; static int32 Sprayings; static float AutoPaintingBudget; + static int32 NoMoreHurricanes; + static float FashionBudget; + static int32 SafeHouseVisits; public: static void Init(void); @@ -89,4 +93,7 @@ public: static int32 FindCriminalRatingNumber(); static void SaveStats(uint8 *buf, uint32 *size); static void LoadStats(uint8 *buf, uint32 size); + static float GetPercentageProgress(); + + static void MoneySpentOnFashion(int32); }; diff --git a/src/core/Streaming.cpp b/src/core/Streaming.cpp index e854da59..985b28c9 100644 --- a/src/core/Streaming.cpp +++ b/src/core/Streaming.cpp @@ -1337,8 +1337,7 @@ CStreaming::LoadInitialPeds(void) void CStreaming::LoadInitialWeapons(void) { - // TODO(Miami): Enable when weapons have been ported - //CStreaming::RequestModel(MI_NIGHTSTICK, STREAMFLAGS_DONT_REMOVE); + CStreaming::RequestModel(MI_NIGHTSTICK, STREAMFLAGS_DONT_REMOVE); CStreaming::RequestModel(MI_MISSILE, STREAMFLAGS_DONT_REMOVE); } @@ -1450,7 +1449,8 @@ CStreaming::StreamVehiclesAndPeds(void) timeBeforeNextLoad--; else if(ms_numVehiclesLoaded <= desiredNumVehiclesLoaded){ CZoneInfo zone; - CTheZones::GetZoneInfoForTimeOfDay(&FindPlayerCoors(), &zone); + CVector coors = FindPlayerCoors(); + CTheZones::GetZoneInfoForTimeOfDay(&coors, &zone); int32 maxReq = -1; int32 mostRequestedRating = 0; for(i = 0; i < CCarCtrl::TOTAL_CUSTOM_CLASSES; i++){ @@ -1524,26 +1524,26 @@ CStreaming::StreamZoneModels(const CVector &pos) bit = 1<m_nVehicleMI < 0) + if(CGangs::GetGangVehicleModel(i) < 0) continue; if((gangCarsToLoad & bit) && (ms_loadedGangCars & bit) == 0){ - RequestModel(CGangs::GetGangInfo(i)->m_nVehicleMI, STREAMFLAGS_DEPENDENCY); + RequestModel(CGangs::GetGangVehicleModel(i), STREAMFLAGS_DEPENDENCY); }else if((gangCarsToLoad & bit) == 0 && ms_loadedGangCars & bit){ - SetModelIsDeletable(CGangs::GetGangInfo(i)->m_nVehicleMI); - SetModelTxdIsDeletable(CGangs::GetGangInfo(i)->m_nVehicleMI); + SetModelIsDeletable(CGangs::GetGangVehicleModel(i)); + SetModelTxdIsDeletable(CGangs::GetGangVehicleModel(i)); } } ms_loadedGangCars = gangCarsToLoad; @@ -1563,10 +1563,10 @@ CStreaming::RemoveCurrentZonesModels(void) } for(i = 0; i < NUM_GANGS; i++){ - SetModelIsDeletable(MI_GANG01 + i*2); - SetModelIsDeletable(MI_GANG01 + i*2 + 1); - if(CGangs::GetGangInfo(i)->m_nVehicleMI != -1) - SetModelIsDeletable(CGangs::GetGangInfo(i)->m_nVehicleMI); + SetModelIsDeletable(CGangs::GetGangPedModel1(i)); + SetModelIsDeletable(CGangs::GetGangPedModel2(i)); + if(CGangs::GetGangVehicleModel(i) != -1) + SetModelIsDeletable(CGangs::GetGangVehicleModel(i)); } ms_currentPedGrp = -1; diff --git a/src/core/SurfaceTable.cpp b/src/core/SurfaceTable.cpp index 08a84cfd..9076a9a6 100644 --- a/src/core/SurfaceTable.cpp +++ b/src/core/SurfaceTable.cpp @@ -56,40 +56,42 @@ int CSurfaceTable::GetAdhesionGroup(uint8 surfaceType) { switch(surfaceType){ - case SURFACE_0: return ADHESIVE_ROAD; - case SURFACE_1: return ADHESIVE_ROAD; - case SURFACE_2: return ADHESIVE_LOOSE; - case SURFACE_3: return ADHESIVE_LOOSE; - case SURFACE_4: return ADHESIVE_HARD; - case SURFACE_5: return ADHESIVE_ROAD; - case SURFACE_6: return ADHESIVE_HARD; - case SURFACE_7: return ADHESIVE_HARD; - case SURFACE_8: return ADHESIVE_HARD; - case SURFACE_9: return ADHESIVE_HARD; - case SURFACE_10: return ADHESIVE_HARD; - case SURFACE_11: return ADHESIVE_HARD; - case SURFACE_12: return ADHESIVE_HARD; - case SURFACE_13: return ADHESIVE_HARD; - case SURFACE_14: return ADHESIVE_HARD; - case SURFACE_15: return ADHESIVE_HARD; - case SURFACE_16: return ADHESIVE_HARD; - case SURFACE_17: return ADHESIVE_RUBBER; - case SURFACE_18: return ADHESIVE_LOOSE; - case SURFACE_19: return ADHESIVE_WET; - case SURFACE_20: return ADHESIVE_ROAD; - case SURFACE_21: return ADHESIVE_ROAD; - case SURFACE_22: return ADHESIVE_ROAD; - case SURFACE_23: return ADHESIVE_RUBBER; - case SURFACE_24: return ADHESIVE_HARD; - case SURFACE_25: return ADHESIVE_LOOSE; - case SURFACE_26: return ADHESIVE_LOOSE; - case SURFACE_27: return ADHESIVE_HARD; - case SURFACE_28: return ADHESIVE_HARD; - case SURFACE_29: return ADHESIVE_RUBBER; - case SURFACE_30: return ADHESIVE_LOOSE; - case SURFACE_31: return ADHESIVE_HARD; - case SURFACE_32: return ADHESIVE_HARD; - default: return ADHESIVE_ROAD; + case SURFACE_DEFAULT: return ADHESIVE_ROAD; + case SURFACE_TARMAC: return ADHESIVE_ROAD; + case SURFACE_GRASS: return ADHESIVE_LOOSE; + case SURFACE_GRAVEL: return ADHESIVE_LOOSE; + case SURFACE_MUD_DRY: return ADHESIVE_HARD; + case SURFACE_PAVEMENT: return ADHESIVE_ROAD; + case SURFACE_CAR: return ADHESIVE_HARD; + case SURFACE_GLASS: return ADHESIVE_HARD; + case SURFACE_TRANSPARENT_CLOTH: return ADHESIVE_HARD; + case SURFACE_GARAGE_DOOR: return ADHESIVE_HARD; + case SURFACE_CAR_PANEL: return ADHESIVE_HARD; + case SURFACE_THICK_METAL_PLATE: return ADHESIVE_HARD; + case SURFACE_SCAFFOLD_POLE: return ADHESIVE_HARD; + case SURFACE_LAMP_POST: return ADHESIVE_HARD; + case SURFACE_FIRE_HYDRANT: return ADHESIVE_HARD; + case SURFACE_GIRDER: return ADHESIVE_HARD; + case SURFACE_METAL_CHAIN_FENCE: return ADHESIVE_HARD; + case SURFACE_PED: return ADHESIVE_RUBBER; + case SURFACE_SAND: return ADHESIVE_SAND; + case SURFACE_WATER: return ADHESIVE_WET; + case SURFACE_WOOD_CRATES: return ADHESIVE_ROAD; + case SURFACE_WOOD_BENCH: return ADHESIVE_ROAD; + case SURFACE_WOOD_SOLID: return ADHESIVE_ROAD; + case SURFACE_RUBBER: return ADHESIVE_RUBBER; + case SURFACE_PLASTIC: return ADHESIVE_HARD; + case SURFACE_HEDGE: return ADHESIVE_LOOSE; + case SURFACE_STEEP_CLIFF: return ADHESIVE_LOOSE; + case SURFACE_CONTAINER: return ADHESIVE_HARD; + case SURFACE_NEWS_VENDOR: return ADHESIVE_HARD; + case SURFACE_WHEELBASE: return ADHESIVE_RUBBER; + case SURFACE_CARDBOARDBOX: return ADHESIVE_LOOSE; + case SURFACE_TRANSPARENT_STONE: return ADHESIVE_HARD; + case SURFACE_METAL_GATE: return ADHESIVE_HARD; + case SURFACE_SAND_BEACH: return ADHESIVE_SAND; + case SURFACE_CONCRETE_BEACH: return ADHESIVE_ROAD; + default: return ADHESIVE_ROAD; } } @@ -97,40 +99,45 @@ float CSurfaceTable::GetWetMultiplier(uint8 surfaceType) { switch(surfaceType){ - case SURFACE_0: - case SURFACE_1: - case SURFACE_4: - case SURFACE_5: - case SURFACE_8: - case SURFACE_20: - case SURFACE_21: - case SURFACE_22: - case SURFACE_25: - case SURFACE_30: - case SURFACE_31: + case SURFACE_DEFAULT: + case SURFACE_TARMAC: + case SURFACE_MUD_DRY: + case SURFACE_PAVEMENT: + case SURFACE_TRANSPARENT_CLOTH: + case SURFACE_WOOD_CRATES: + case SURFACE_WOOD_BENCH: + case SURFACE_WOOD_SOLID: + case SURFACE_HEDGE: + case SURFACE_CARDBOARDBOX: + case SURFACE_TRANSPARENT_STONE: + case SURFACE_CONCRETE_BEACH: return 1.0f - CWeather::WetRoads*0.25f; - case SURFACE_2: - case SURFACE_6: - case SURFACE_7: - case SURFACE_9: - case SURFACE_10: - case SURFACE_11: - case SURFACE_12: - case SURFACE_13: - case SURFACE_14: - case SURFACE_15: - case SURFACE_16: - case SURFACE_17: - case SURFACE_23: - case SURFACE_24: - case SURFACE_26: - case SURFACE_27: - case SURFACE_28: - case SURFACE_29: - case SURFACE_32: + case SURFACE_GRASS: + case SURFACE_CAR: + case SURFACE_GLASS: + case SURFACE_GARAGE_DOOR: + case SURFACE_CAR_PANEL: + case SURFACE_THICK_METAL_PLATE: + case SURFACE_SCAFFOLD_POLE: + case SURFACE_LAMP_POST: + case SURFACE_FIRE_HYDRANT: + case SURFACE_GIRDER: + case SURFACE_METAL_CHAIN_FENCE: + case SURFACE_PED: + case SURFACE_RUBBER: + case SURFACE_PLASTIC: + case SURFACE_STEEP_CLIFF: + case SURFACE_CONTAINER: + case SURFACE_NEWS_VENDOR: + case SURFACE_WHEELBASE: + case SURFACE_METAL_GATE: return 1.0f - CWeather::WetRoads*0.4f; + case SURFACE_SAND: + case SURFACE_SAND_BEACH: + return 1.0f - CWeather::WetRoads*0.5f; + default: return 1.0f; } diff --git a/src/core/SurfaceTable.h b/src/core/SurfaceTable.h index 12246dce..d8f9be3d 100644 --- a/src/core/SurfaceTable.h +++ b/src/core/SurfaceTable.h @@ -1,86 +1,42 @@ #pragma once - -enum -{ - SURFACE_0, - SURFACE_1, - SURFACE_2, - SURFACE_3, - SURFACE_4, - SURFACE_5, - SURFACE_6, - SURFACE_7, - SURFACE_8, - SURFACE_9, - SURFACE_10, - SURFACE_11, - SURFACE_12, - SURFACE_13, - SURFACE_14, - SURFACE_15, - SURFACE_16, - SURFACE_17, - SURFACE_18, - SURFACE_19, - SURFACE_20, - SURFACE_21, - SURFACE_22, - SURFACE_23, - SURFACE_24, - SURFACE_25, - SURFACE_26, - SURFACE_27, - SURFACE_28, - SURFACE_29, - SURFACE_30, - SURFACE_31, - SURFACE_32, - - NUMSURFACETYPES -}; - -// From nick -// TODO: check and use this enum eSurfaceType { SURFACE_DEFAULT, SURFACE_TARMAC, SURFACE_GRASS, - SURFACE_DIRT, - SURFACE_DIRTTRACK, + SURFACE_GRAVEL, + SURFACE_MUD_DRY, SURFACE_PAVEMENT, - SURFACE_METAL6, + SURFACE_CAR, SURFACE_GLASS, - SURFACE_SCAFFOLD, - SURFACE_METAL_DOOR, // garage door - SURFACE_BILLBOARD, - SURFACE_STEEL, //? - SURFACE_METAL_POLE, // ? - SURFACE_STREET_LIGHT, - SURFACE_METAL14, - SURFACE_METAL15, - SURFACE_METAL_FENCE, - SURFACE_FLESH, + SURFACE_TRANSPARENT_CLOTH, + SURFACE_GARAGE_DOOR, + SURFACE_CAR_PANEL, + SURFACE_THICK_METAL_PLATE, + SURFACE_SCAFFOLD_POLE, + SURFACE_LAMP_POST, + SURFACE_FIRE_HYDRANT, + SURFACE_GIRDER, + SURFACE_METAL_CHAIN_FENCE, + SURFACE_PED, SURFACE_SAND, - SURFACE_PUDDLE, - SURFACE_WOOD, - SURFACE_WOOD_BOX, - SURFACE_WOOD_PLANK, - SURFACE_TIRE, - SURFACE_HARD24, + SURFACE_WATER, + SURFACE_WOOD_CRATES, + SURFACE_WOOD_BENCH, + SURFACE_WOOD_SOLID, + SURFACE_RUBBER, + SURFACE_PLASTIC, SURFACE_HEDGE, - SURFACE_STONE, - SURFACE_METAL27, - SURFACE_METAL28, - SURFACE_RUBBER29, - SURFACE_LOOSE30, - SURFACE_BOLLARD, - SURFACE_GATE, - - // These are illegal - SURFACE_SAND33, - SURFACE_ROAD34, + SURFACE_STEEP_CLIFF, + SURFACE_CONTAINER, + SURFACE_NEWS_VENDOR, + SURFACE_WHEELBASE, + SURFACE_CARDBOARDBOX, + SURFACE_TRANSPARENT_STONE, + SURFACE_METAL_GATE, + SURFACE_SAND_BEACH, + SURFACE_CONCRETE_BEACH, }; enum @@ -89,6 +45,7 @@ enum ADHESIVE_HARD, ADHESIVE_ROAD, ADHESIVE_LOOSE, + ADHESIVE_SAND, ADHESIVE_WET, NUMADHESIVEGROUPS diff --git a/src/core/TempColModels.cpp b/src/core/TempColModels.cpp index f20923f2..a4814759 100644 --- a/src/core/TempColModels.cpp +++ b/src/core/TempColModels.cpp @@ -66,7 +66,7 @@ CTempColModels::Initialise(void) #else for (i = 0; i < ARRAY_SIZE(s_aPedGSpheres); i++) { #endif - s_aPedSpheres[i].surface = SURFACE_FLESH; + s_aPedSpheres[i].surface = SURFACE_PED; s_aPedSpheres[i].piece = 0; } @@ -85,7 +85,7 @@ CTempColModels::Initialise(void) s_aPed2Spheres[2].center = CVector(0.0f, -0.35f, -0.9f); for (i = 0; i < ARRAY_SIZE(s_aPed2Spheres); i++) { - s_aPed2Spheres[i].surface = SURFACE_FLESH; + s_aPed2Spheres[i].surface = SURFACE_PED; s_aPed2Spheres[i].piece = 0; } @@ -106,10 +106,10 @@ CTempColModels::Initialise(void) s_aPedGSpheres[2].center = CVector(0.0f, 0.25f, -0.9f); s_aPedGSpheres[3].center = CVector(0.0f, 0.65f, -0.9f); - s_aPedGSpheres[0].surface = SURFACE_FLESH; - s_aPedGSpheres[1].surface = SURFACE_FLESH; - s_aPedGSpheres[2].surface = SURFACE_FLESH; - s_aPedGSpheres[3].surface = SURFACE_FLESH; + s_aPedGSpheres[0].surface = SURFACE_PED; + s_aPedGSpheres[1].surface = SURFACE_PED; + s_aPedGSpheres[2].surface = SURFACE_PED; + s_aPedGSpheres[3].surface = SURFACE_PED; s_aPedGSpheres[0].piece = 4; s_aPedGSpheres[1].piece = 1; s_aPedGSpheres[2].piece = 0; @@ -131,7 +131,7 @@ CTempColModels::Initialise(void) s_aDoorSpheres[2].center = CVector(0.0f, -0.6f, 0.25f); for (i = 0; i < ARRAY_SIZE(s_aDoorSpheres); i++) { - s_aDoorSpheres[i].surface = SURFACE_BILLBOARD; + s_aDoorSpheres[i].surface = SURFACE_CAR_PANEL; s_aDoorSpheres[i].piece = 0; } @@ -151,7 +151,7 @@ CTempColModels::Initialise(void) s_aBumperSpheres[3].center = CVector(-0.85f, -0.05f, 0.0f); for (i = 0; i < ARRAY_SIZE(s_aBumperSpheres); i++) { - s_aBumperSpheres[i].surface = SURFACE_BILLBOARD; + s_aBumperSpheres[i].surface = SURFACE_CAR_PANEL; s_aBumperSpheres[i].piece = 0; } @@ -171,7 +171,7 @@ CTempColModels::Initialise(void) s_aPanelSpheres[3].center = CVector(-0.15f, 0.45f, 0.0f); for (i = 0; i < ARRAY_SIZE(s_aPanelSpheres); i++) { - s_aPanelSpheres[i].surface = SURFACE_BILLBOARD; + s_aPanelSpheres[i].surface = SURFACE_CAR_PANEL; s_aPanelSpheres[i].piece = 0; } @@ -191,7 +191,7 @@ CTempColModels::Initialise(void) s_aBonnetSpheres[3].center = CVector(0.4f, 0.9f, 0.0f); for (i = 0; i < ARRAY_SIZE(s_aBonnetSpheres); i++) { - s_aBonnetSpheres[i].surface = SURFACE_BILLBOARD; + s_aBonnetSpheres[i].surface = SURFACE_CAR_PANEL; s_aBonnetSpheres[i].piece = 0; } @@ -211,7 +211,7 @@ CTempColModels::Initialise(void) s_aBootSpheres[3].center = CVector(0.4f, -0.6f, 0.0f); for (i = 0; i < ARRAY_SIZE(s_aBootSpheres); i++) { - s_aBootSpheres[i].surface = SURFACE_BILLBOARD; + s_aBootSpheres[i].surface = SURFACE_CAR_PANEL; s_aBootSpheres[i].piece = 0; } @@ -233,7 +233,7 @@ CTempColModels::Initialise(void) #else for (i = 0; i < ARRAY_SIZE(s_aBootSpheres); i++) { #endif - s_aWheelSpheres[i].surface = SURFACE_RUBBER29; + s_aWheelSpheres[i].surface = SURFACE_WHEELBASE; s_aWheelSpheres[i].piece = 0; } @@ -255,7 +255,7 @@ CTempColModels::Initialise(void) #else for (i = 0; i < ARRAY_SIZE(s_aBootSpheres); i++) { #endif - s_aBodyPartSpheres1[i].surface = SURFACE_FLESH; + s_aBodyPartSpheres1[i].surface = SURFACE_PED; s_aBodyPartSpheres1[i].piece = 0; } @@ -277,7 +277,7 @@ CTempColModels::Initialise(void) #else for (i = 0; i < ARRAY_SIZE(s_aBootSpheres); i++) { #endif - s_aBodyPartSpheres2[i].surface = SURFACE_FLESH; + s_aBodyPartSpheres2[i].surface = SURFACE_PED; s_aBodyPartSpheres2[i].piece = 0; } diff --git a/src/core/Timer.h b/src/core/Timer.h index 004cda4d..e7b6fec8 100644 --- a/src/core/Timer.h +++ b/src/core/Timer.h @@ -58,7 +58,7 @@ public: friend bool GenericSave(int file); #ifdef FIX_BUGS - static float GetDefaultTimeStep(void) { return 5.0f / 3.0f; } + static float GetDefaultTimeStep(void) { return 50.0f / 30.0f; } static float GetTimeStepFix(void) { return GetTimeStep() / GetDefaultTimeStep(); } #endif }; diff --git a/src/core/World.cpp b/src/core/World.cpp index 8c69d846..06108c5c 100644 --- a/src/core/World.cpp +++ b/src/core/World.cpp @@ -33,22 +33,24 @@ CColPoint gaTempSphereColPoints[MAX_COLLISION_POINTS]; -CPtrList CWorld::ms_bigBuildingsList[4];// = (CPtrList*)0x6FAB60; -CPtrList CWorld::ms_listMovingEntityPtrs;// = *(CPtrList*)0x8F433C; -CSector CWorld::ms_aSectors[NUMSECTORS_Y][NUMSECTORS_X];// = (CSector (*)[NUMSECTORS_Y])0x665608; -uint16 CWorld::ms_nCurrentScanCode;// = *(uint16*)0x95CC64; +CPtrList CWorld::ms_bigBuildingsList[4]; +CPtrList CWorld::ms_listMovingEntityPtrs; +CSector CWorld::ms_aSectors[NUMSECTORS_Y][NUMSECTORS_X]; +uint16 CWorld::ms_nCurrentScanCode; -uint8 CWorld::PlayerInFocus;// = *(uint8 *)0x95CD61; +uint8 CWorld::PlayerInFocus; CPlayerInfo CWorld::Players[NUMPLAYERS]; -bool CWorld::bNoMoreCollisionTorque;// = *(bool*)0x95CDCC; -CEntity *CWorld::pIgnoreEntity;// = *(CEntity**)0x8F6494; -bool CWorld::bIncludeDeadPeds;// = *(bool*)0x95CD8F; -bool CWorld::bSecondShift;// = *(bool*)0x95CD54; -bool CWorld::bForceProcessControl;// = *(bool*)0x95CD6C; -bool CWorld::bProcessCutsceneOnly;// = *(bool*)0x95CD8B; +bool CWorld::bNoMoreCollisionTorque; +CEntity *CWorld::pIgnoreEntity; +bool CWorld::bIncludeDeadPeds; +bool CWorld::bSecondShift; +bool CWorld::bForceProcessControl; +bool CWorld::bProcessCutsceneOnly; -bool CWorld::bDoingCarCollisions;// = *(bool*)0x95CD8C; -bool CWorld::bIncludeCarTyres;// = *(bool*)0x95CDAA; +bool CWorld::bDoingCarCollisions; +bool CWorld::bIncludeCarTyres; + +CColPoint CWorld::m_aTempColPts[MAX_COLLISION_POINTS]; void CWorld::Initialise() @@ -165,7 +167,7 @@ CWorld::CameraToIgnoreThisObject(CEntity *ent) bool CWorld::ProcessLineOfSight(const CVector &point1, const CVector &point2, CColPoint &point, CEntity *&entity, bool checkBuildings, bool checkVehicles, bool checkPeds, bool checkObjects, - bool checkDummies, bool ignoreSeeThrough, bool ignoreSomeObjects) + bool checkDummies, bool ignoreSeeThrough, bool ignoreSomeObjects, bool ignoreShootThrough) { int x, xstart, xend; int y, ystart, yend; @@ -184,7 +186,7 @@ CWorld::ProcessLineOfSight(const CVector &point1, const CVector &point2, CColPoi #define LOSARGS \ CColLine(point1, point2), point, dist, entity, checkBuildings, checkVehicles, checkPeds, checkObjects, \ - checkDummies, ignoreSeeThrough, ignoreSomeObjects + checkDummies, ignoreSeeThrough, ignoreSomeObjects, ignoreShootThrough if(xstart == xend && ystart == yend) { // Only one sector @@ -266,7 +268,7 @@ CWorld::ProcessLineOfSight(const CVector &point1, const CVector &point2, CColPoi bool CWorld::ProcessLineOfSightSector(CSector §or, const CColLine &line, CColPoint &point, float &dist, CEntity *&entity, bool checkBuildings, bool checkVehicles, bool checkPeds, bool checkObjects, - bool checkDummies, bool ignoreSeeThrough, bool ignoreSomeObjects) + bool checkDummies, bool ignoreSeeThrough, bool ignoreSomeObjects, bool ignoreShootThrough) { float mindist = dist; bool deadPeds = !!bIncludeDeadPeds; @@ -274,39 +276,39 @@ CWorld::ProcessLineOfSightSector(CSector §or, const CColLine &line, CColPoin if(checkBuildings) { ProcessLineOfSightSectorList(sector.m_lists[ENTITYLIST_BUILDINGS], line, point, mindist, entity, - ignoreSeeThrough); + ignoreSeeThrough, false, ignoreShootThrough); ProcessLineOfSightSectorList(sector.m_lists[ENTITYLIST_BUILDINGS_OVERLAP], line, point, mindist, entity, - ignoreSeeThrough); + ignoreSeeThrough, false, ignoreShootThrough); } if(checkVehicles) { ProcessLineOfSightSectorList(sector.m_lists[ENTITYLIST_VEHICLES], line, point, mindist, entity, - ignoreSeeThrough); + ignoreSeeThrough, false, ignoreShootThrough); ProcessLineOfSightSectorList(sector.m_lists[ENTITYLIST_VEHICLES_OVERLAP], line, point, mindist, entity, - ignoreSeeThrough); + ignoreSeeThrough, false, ignoreShootThrough); } if(checkPeds) { if(deadPeds) bIncludeDeadPeds = true; ProcessLineOfSightSectorList(sector.m_lists[ENTITYLIST_PEDS], line, point, mindist, entity, - ignoreSeeThrough); + ignoreSeeThrough, false, ignoreShootThrough); ProcessLineOfSightSectorList(sector.m_lists[ENTITYLIST_PEDS_OVERLAP], line, point, mindist, entity, - ignoreSeeThrough); + ignoreSeeThrough, false, ignoreShootThrough); bIncludeDeadPeds = false; } if(checkObjects) { ProcessLineOfSightSectorList(sector.m_lists[ENTITYLIST_OBJECTS], line, point, mindist, entity, - ignoreSeeThrough, ignoreSomeObjects); + ignoreSeeThrough, ignoreSomeObjects, ignoreShootThrough); ProcessLineOfSightSectorList(sector.m_lists[ENTITYLIST_OBJECTS_OVERLAP], line, point, mindist, entity, - ignoreSeeThrough, ignoreSomeObjects); + ignoreSeeThrough, ignoreSomeObjects, ignoreShootThrough); } if(checkDummies) { ProcessLineOfSightSectorList(sector.m_lists[ENTITYLIST_DUMMIES], line, point, mindist, entity, - ignoreSeeThrough); + ignoreSeeThrough, false, ignoreShootThrough); ProcessLineOfSightSectorList(sector.m_lists[ENTITYLIST_DUMMIES_OVERLAP], line, point, mindist, entity, - ignoreSeeThrough); + ignoreSeeThrough, false, ignoreShootThrough); } bIncludeDeadPeds = deadPeds; @@ -320,7 +322,7 @@ CWorld::ProcessLineOfSightSector(CSector §or, const CColLine &line, CColPoin bool CWorld::ProcessLineOfSightSectorList(CPtrList &list, const CColLine &line, CColPoint &point, float &dist, - CEntity *&entity, bool ignoreSeeThrough, bool ignoreSomeObjects) + CEntity *&entity, bool ignoreSeeThrough, bool ignoreSomeObjects, bool ignoreShootThrough) { bool deadPeds = false; float mindist = dist; @@ -340,21 +342,6 @@ CWorld::ProcessLineOfSightSectorList(CPtrList &list, const CColLine &line, CColP if(e->IsPed()) { if(e->bUsesCollision || deadPeds && ((CPed *)e)->m_nPedState == PED_DEAD) { colmodel = ((CPedModelInfo *)CModelInfo::GetModelInfo(e->GetModelIndex()))->AnimatePedColModelSkinned(e->GetClump()); -/* this should all be gone, right? - if(((CPed *)e)->UseGroundColModel()) - colmodel = &CTempColModels::ms_colModelPedGroundHit; - else -#ifdef ANIMATE_PED_COL_MODEL - colmodel = CPedModelInfo::AnimatePedColModel( - ((CPedModelInfo *)CModelInfo::GetModelInfo(e->GetModelIndex())) - ->GetHitColModel(), - RpClumpGetFrame(e->GetClump())); -#else - colmodel = - ((CPedModelInfo *)CModelInfo::GetModelInfo(e->GetModelIndex())) - ->GetHitColModel(); -#endif -*/ } else colmodel = nil; @@ -362,7 +349,7 @@ CWorld::ProcessLineOfSightSectorList(CPtrList &list, const CColLine &line, CColP colmodel = CModelInfo::GetModelInfo(e->GetModelIndex())->GetColModel(); if(colmodel && CCollision::ProcessLineOfSight(line, e->GetMatrix(), *colmodel, point, dist, - ignoreSeeThrough)) + ignoreSeeThrough, ignoreShootThrough)) entity = e; } } @@ -451,7 +438,7 @@ CWorld::ProcessVerticalLineSectorList(CPtrList &list, const CColLine &line, CCol colmodel = CModelInfo::GetModelInfo(e->GetModelIndex())->GetColModel(); if(CCollision::ProcessVerticalLine(line, e->GetMatrix(), *colmodel, point, dist, - ignoreSeeThrough, poly)) + ignoreSeeThrough, false, poly)) entity = e; } } @@ -652,7 +639,7 @@ CWorld::GetIsLineOfSightSectorListClear(CPtrList &list, const CColLine &line, bo colmodel = CModelInfo::GetModelInfo(e->GetModelIndex())->GetColModel(); - if(CCollision::TestLineOfSight(line, e->GetMatrix(), *colmodel, ignoreSeeThrough)) + if(CCollision::TestLineOfSight(line, e->GetMatrix(), *colmodel, ignoreSeeThrough, false)) return false; } } @@ -1828,18 +1815,21 @@ void CWorld::RepositionOneObject(CEntity *pEntity) { int16 modelId = pEntity->GetModelIndex(); - if (IsTrafficLight(modelId) || IsTreeModel(modelId) || modelId == MI_PARKINGMETER || - modelId == MI_PHONEBOOTH1 || modelId == MI_WASTEBIN || modelId == MI_BIN || modelId == MI_POSTBOX1 || - modelId == MI_NEWSSTAND || modelId == MI_TRAFFICCONE || modelId == MI_DUMP1 || - modelId == MI_ROADWORKBARRIER1 || modelId == MI_BUSSIGN1 || modelId == MI_NOPARKINGSIGN1 || - modelId == MI_PHONESIGN || modelId == MI_TAXISIGN || modelId == MI_FISHSTALL01 || - modelId == MI_FISHSTALL02 || modelId == MI_FISHSTALL03 || modelId == MI_FISHSTALL04 || - modelId == MI_BAGELSTAND2 || modelId == MI_FIRE_HYDRANT || modelId == MI_BOLLARDLIGHT || - modelId == MI_PARKTABLE) { + if (modelId == MI_PARKINGMETER || modelId == MI_PHONEBOOTH1 || modelId == MI_WASTEBIN || + modelId == MI_BIN || modelId == MI_POSTBOX1 || modelId == MI_NEWSSTAND || modelId == MI_TRAFFICCONE || + modelId == MI_DUMP1 || modelId == MI_ROADWORKBARRIER1 || modelId == MI_BUSSIGN1 || modelId == MI_NOPARKINGSIGN1 || + modelId == MI_PHONESIGN || modelId == MI_FIRE_HYDRANT || modelId == MI_BOLLARDLIGHT || + modelId == MI_PARKTABLE || modelId == MI_PARKINGMETER2 || modelId == MI_TELPOLE02 || + modelId == MI_PARKBENCH || modelId == MI_BARRIER1 || IsTreeModel(modelId) || + IsLightThatNeedsRepositioning(modelId) + ) { CVector &position = pEntity->GetMatrix().GetPosition(); - float fBoundingBoxMinZ = pEntity->GetColModel()->boundingBox.min.z; + CColModel *pColModel = pEntity->GetColModel(); + float fBoundingBoxMinZ = pColModel->boundingBox.min.z; + float fHeight = pColModel->boundingBox.max.z - pColModel->boundingBox.min.z; + if(fHeight < OBJECT_REPOSITION_OFFSET_Z) fHeight = OBJECT_REPOSITION_OFFSET_Z; position.z = CWorld::FindGroundZFor3DCoord(position.x, position.y, - position.z + OBJECT_REPOSITION_OFFSET_Z, nil) - + position.z + fHeight, nil) - fBoundingBoxMinZ; pEntity->m_matrix.UpdateRW(); pEntity->UpdateRwFrame(); @@ -2240,3 +2230,58 @@ CWorld::UseDetonator(CEntity *pEntity) } CProjectileInfo::RemoveDetonatorProjectiles(); } + +bool +CWorld::IsWanderPathClear(CVector const& point1, CVector const& point2, float distance, int maxSteps) +{ + if (Abs(point1.z - point2.z) > distance) + return false; + if (!GetIsLineOfSightClear(point1, point2, true, false, false, false, false, false, false)) + return false; + CVector vecBetween = point2 - point1; + uint32 nSteps = Max(vecBetween.Magnitude(), maxSteps); + if (nSteps == 0) + return true; + vecBetween.Normalise(); + uint32 step = 1; + for (step = 1; step < nSteps; step++) { + CVector posThisStep = point1 + vecBetween * step; + float level; + if (!CWaterLevel::GetWaterLevel(posThisStep, &level, false)) + continue; + posThisStep.z = level; + AdvanceCurrentScanCode(); + + CVector vecCheckedPos(posThisStep.x, posThisStep.y, Max(point1.z, point2.z)); + CColPoint colpoint; + CEntity* entity; + if (!ProcessVerticalLineSector(*GetSector(GetSectorIndexX(posThisStep.x), GetSectorIndexY(posThisStep.y)), + CColLine(posThisStep, vecCheckedPos), colpoint, entity, true, false, false, false, false, false, nil)) + return false; + } + + CVector posThisStep = point1; + AdvanceCurrentScanCode(); + CVector vecCheckedPos(posThisStep.x, posThisStep.y, point1.z - 5.0f); + + CColPoint colpoint; + CEntity* entity; + if (!ProcessVerticalLineSector(*GetSector(GetSectorIndexX(posThisStep.x), GetSectorIndexY(posThisStep.y)), + CColLine(posThisStep, vecCheckedPos), colpoint, entity, true, false, false, false, false, false, nil)) + return false; + + float heightNextStep = colpoint.point.z + 0.5f; + for (step = 1; step < nSteps; step++) { + CVector posThisStep = point1 + vecBetween * step; + posThisStep.z = heightNextStep; + AdvanceCurrentScanCode(); + CVector vecCheckedPos(posThisStep.x, posThisStep.y, heightNextStep - 2.0f); + if (!ProcessVerticalLineSector(*GetSector(GetSectorIndexX(posThisStep.x), GetSectorIndexY(posThisStep.y)), + CColLine(posThisStep, vecCheckedPos), colpoint, entity, true, false, false, false, false, false, nil)) + return false; + if (Abs(colpoint.point.z - heightNextStep) > 1.0f) + return false; + heightNextStep = colpoint.point.z + 0.5f; + } + return true; +} diff --git a/src/core/World.h b/src/core/World.h index bc905bf5..3da774ba 100644 --- a/src/core/World.h +++ b/src/core/World.h @@ -71,6 +71,7 @@ public: static bool bProcessCutsceneOnly; static bool bDoingCarCollisions; static bool bIncludeCarTyres; + static CColPoint m_aTempColPts[MAX_COLLISION_POINTS]; static void Remove(CEntity *entity); static void Add(CEntity *entity); @@ -90,9 +91,9 @@ public: static bool CameraToIgnoreThisObject(CEntity *ent); - static bool ProcessLineOfSight(const CVector &point1, const CVector &point2, CColPoint &point, CEntity *&entity, bool checkBuildings, bool checkVehicles, bool checkPeds, bool checkObjects, bool checkDummies, bool ignoreSeeThrough, bool ignoreSomeObjects = false); - static bool ProcessLineOfSightSector(CSector §or, const CColLine &line, CColPoint &point, float &dist, CEntity *&entity, bool checkBuildings, bool checkVehicles, bool checkPeds, bool checkObjects, bool checkDummies, bool ignoreSeeThrough, bool ignoreSomeObjects = false); - static bool ProcessLineOfSightSectorList(CPtrList &list, const CColLine &line, CColPoint &point, float &dist, CEntity *&entity, bool ignoreSeeThrough, bool ignoreSomeObjects = false); + static bool ProcessLineOfSight(const CVector &point1, const CVector &point2, CColPoint &point, CEntity *&entity, bool checkBuildings, bool checkVehicles, bool checkPeds, bool checkObjects, bool checkDummies, bool ignoreSeeThrough, bool ignoreSomeObjects = false, bool ignoreShootThrough = false); + static bool ProcessLineOfSightSector(CSector §or, const CColLine &line, CColPoint &point, float &dist, CEntity *&entity, bool checkBuildings, bool checkVehicles, bool checkPeds, bool checkObjects, bool checkDummies, bool ignoreSeeThrough, bool ignoreSomeObjects, bool ignoreShootThrough); + static bool ProcessLineOfSightSectorList(CPtrList &list, const CColLine &line, CColPoint &point, float &dist, CEntity *&entity, bool ignoreSeeThrough, bool ignoreSomeObjects, bool ignoreShootThrough); static bool ProcessVerticalLine(const CVector &point1, float z2, CColPoint &point, CEntity *&entity, bool checkBuildings, bool checkVehicles, bool checkPeds, bool checkObjects, bool checkDummies, bool ignoreSeeThrough, CStoredCollPoly *poly); static bool ProcessVerticalLineSector(CSector §or, const CColLine &line, CColPoint &point, CEntity *&entity, bool checkBuildings, bool checkVehicles, bool checkPeds, bool checkObjects, bool checkDummies, bool ignoreSeeThrough, CStoredCollPoly *poly); static bool ProcessVerticalLineSectorList(CPtrList &list, const CColLine &line, CColPoint &point, float &dist, CEntity *&entity, bool ignoreSeeThrough, CStoredCollPoly *poly); @@ -125,6 +126,8 @@ public: static void CallOffChaseForAreaSectorListVehicles(CPtrList& list, float x1, float y1, float x2, float y2, float fStartX, float fStartY, float fEndX, float fEndY); static void CallOffChaseForAreaSectorListPeds(CPtrList& list, float x1, float y1, float x2, float y2); + static bool IsWanderPathClear(CVector const&, CVector const&, float, int); + static float GetSectorX(float f) { return ((f - WORLD_MIN_X)/SECTOR_SIZE_X); } static float GetSectorY(float f) { return ((f - WORLD_MIN_Y)/SECTOR_SIZE_Y); } static int GetSectorIndexX(float f) { return (int)GetSectorX(f); } diff --git a/src/core/Zones.cpp b/src/core/Zones.cpp index 8e73a07b..84b5ca29 100644 --- a/src/core/Zones.cpp +++ b/src/core/Zones.cpp @@ -112,6 +112,7 @@ CTheZones::Init(void) memset(&MapZoneArray[i], 0, sizeof(CZone)); MapZoneArray[i].type = ZONE_MAPZONE; } + TotalNumberOfMapZones = 1; strcpy(MapZoneArray[0].name, "THEMAP"); MapZoneArray[0].minx = -2400.0f; MapZoneArray[0].miny = -2000.0f; @@ -724,17 +725,17 @@ CTheZones::LoadAllZones(uint8 *buffer, uint32 size) for(i = 0; i < ARRAY_SIZE(NavigationZoneArray); i++){ NavigationZoneArray[i] = ReadSaveBuf(buffer); - NavigationZoneArray[i].child = GetPointerForZoneIndex((int32)NavigationZoneArray[i].child); - NavigationZoneArray[i].parent = GetPointerForZoneIndex((int32)NavigationZoneArray[i].parent); - NavigationZoneArray[i].next = GetPointerForZoneIndex((int32)NavigationZoneArray[i].next); + NavigationZoneArray[i].child = GetPointerForZoneIndex((uintptr)NavigationZoneArray[i].child); + NavigationZoneArray[i].parent = GetPointerForZoneIndex((uintptr)NavigationZoneArray[i].parent); + NavigationZoneArray[i].next = GetPointerForZoneIndex((uintptr)NavigationZoneArray[i].next); } for(i = 0; i < ARRAY_SIZE(InfoZoneArray); i++){ InfoZoneArray[i] = ReadSaveBuf(buffer); - InfoZoneArray[i].child = GetPointerForZoneIndex((int32)InfoZoneArray[i].child); - InfoZoneArray[i].parent = GetPointerForZoneIndex((int32)InfoZoneArray[i].parent); - InfoZoneArray[i].next = GetPointerForZoneIndex((int32)InfoZoneArray[i].next); + InfoZoneArray[i].child = GetPointerForZoneIndex((uintptr)InfoZoneArray[i].child); + InfoZoneArray[i].parent = GetPointerForZoneIndex((uintptr)InfoZoneArray[i].parent); + InfoZoneArray[i].next = GetPointerForZoneIndex((uintptr)InfoZoneArray[i].next); } for(i = 0; i < ARRAY_SIZE(ZoneInfoArray); i++) diff --git a/src/core/config.h b/src/core/config.h index 30f6b898..ea31a3c8 100644 --- a/src/core/config.h +++ b/src/core/config.h @@ -66,7 +66,7 @@ enum Config { // Cull zones NUMATTRIBZONES = 704, - NUMHANDLINGS = 106, + NUMOCCLUSIONVOLUMES = 350, PATHNODESIZE = 4500, @@ -95,7 +95,7 @@ enum Config { NUMPACMANPICKUPS = 256, NUMEVENTS = 64, - NUM_CARGENS = 160, + NUM_CARGENS = 185, NUM_PATH_NODES_IN_AUTOPILOT = 8, @@ -135,6 +135,8 @@ enum Config { NUM_CRANES = 8, NUM_EXPLOSIONS = 48, + + NUM_SETPIECES = 96 }; // We'll use this once we're ready to become independent of the game @@ -194,15 +196,13 @@ enum Config { #define FIX_BUGS // fixes bugs that we've came across during reversing, TODO: use this more #define TOGGLEABLE_BETA_FEATURES // toggleable from debug menu. not too many things -#define MORE_LANGUAGES // Add more translations to the game +//#define MORE_LANGUAGES // Add more translations to the game #define DEFAULT_NATIVE_RESOLUTION // Set default video mode to your native resolution (fixes Windows 10 launch) #define USE_TXD_CDIMAGE // generate and load textures from txd.img #define IMPROVED_VIDEOMODE // save and load videomode parameters instead of a magic number //#define USE_TEXTURE_POOL -#ifdef _WIN32 -#define AUDIO_MSS -#else -#define AUDIO_OAL +#ifdef DEBUGMENU +#define RELOADABLES // some debug menu options to reload TXD files #endif // Particle @@ -222,7 +222,6 @@ enum Config { // Hud, frontend and radar #define ASPECT_RATIO_SCALE // Not just makes everything scale with aspect ratio, also adds support for all aspect ratios #define TRIANGULAR_BLIPS // height indicating triangular radar blips, as in VC -#define PS2_SAVE_DIALOG // PS2 style save dialog with transparent black box // #define PS2_LIKE_MENU // An effort to recreate PS2 menu, cycling through tabs, different bg etc. #define MENU_MAP // VC-like menu map. Make sure you have new menu.txd #define SCROLLABLE_STATS_PAGE // only draggable by mouse atm diff --git a/src/core/main.cpp b/src/core/main.cpp index dc61f03f..aefabfc7 100644 --- a/src/core/main.cpp +++ b/src/core/main.cpp @@ -81,7 +81,7 @@ RwRGBA gColourTop; bool gameAlreadyInitialised; float NumberOfChunksLoaded; -#define TOTALNUMCHUNKS 73.0f +#define TOTALNUMCHUNKS 95.0f bool g_SlowMode = false; char version_name[64]; @@ -137,9 +137,10 @@ DoRWStuffStartOfFrame(int16 TopRed, int16 TopGreen, int16 TopBlue, int16 BottomR CRGBA TopColor(TopRed, TopGreen, TopBlue, Alpha); CRGBA BottomColor(BottomRed, BottomGreen, BottomBlue, Alpha); + CDraw::CalculateAspectRatio(); CameraSize(Scene.camera, nil, SCREEN_VIEWWINDOW, SCREEN_ASPECT_RATIO); CVisibilityPlugins::SetRenderWareCamera(Scene.camera); - RwCameraClear(Scene.camera, &gColourTop, rwCAMERACLEARZ); + RwCameraClear(Scene.camera, &TopColor.rwRGBA, rwCAMERACLEARZ); if(!RsCameraBeginUpdate(Scene.camera)) return false; @@ -155,6 +156,7 @@ DoRWStuffStartOfFrame(int16 TopRed, int16 TopGreen, int16 TopBlue, int16 BottomR bool DoRWStuffStartOfFrame_Horizon(int16 TopRed, int16 TopGreen, int16 TopBlue, int16 BottomRed, int16 BottomGreen, int16 BottomBlue, int16 Alpha) { + CDraw::CalculateAspectRatio(); CameraSize(Scene.camera, nil, SCREEN_VIEWWINDOW, SCREEN_ASPECT_RATIO); CVisibilityPlugins::SetRenderWareCamera(Scene.camera); RwCameraClear(Scene.camera, &gColourTop, rwCAMERACLEARZ); @@ -199,13 +201,13 @@ DoFade(void) } } - if(CDraw::FadeValue != 0 || CMenuManager::m_PrefsBrightness < 256){ + if(CDraw::FadeValue != 0 || FrontEndMenuManager.m_PrefsBrightness < 256){ CSprite2d *splash = LoadSplash(nil); CRGBA fadeColor; CRect rect; int fadeValue = CDraw::FadeValue; - float brightness = Min(CMenuManager::m_PrefsBrightness, 256); + float brightness = Min(FrontEndMenuManager.m_PrefsBrightness, 256); if(brightness <= 50) brightness = 50; if(FrontEndMenuManager.m_bMenuActive) @@ -328,7 +330,7 @@ PluginAttach(void) static RwBool Initialise3D(void *param) { - if (RsRwInitialise(param)) + if (RsRwInitialize(param)) { #ifdef DEBUGMENU DebugMenuInit(); @@ -356,6 +358,7 @@ Terminate3D(void) CSprite2d splash; int splashTxdId = -1; +//--MIAMI: done CSprite2d* LoadSplash(const char *name) { @@ -401,22 +404,23 @@ DestroySplashScreen(void) splashTxdId = -1; } +//--MIAMI: done Const char* GetRandomSplashScreen(void) { int index; static int index2 = 0; static char splashName[128]; - static int splashIndex[24] = { - 25, 22, 4, 13, - 1, 21, 14, 16, - 10, 12, 5, 9, - 11, 18, 3, 2, - 19, 23, 7, 17, - 15, 6, 8, 20 + static int splashIndex[12] = { + 1, 2, + 3, 4, + 5, 11, + 6, 8, + 9, 10, + 7, 12 }; - index = splashIndex[4*index2 + CGeneral::GetRandomNumberInRange(0, 3)]; + index = splashIndex[2*index2 + CGeneral::GetRandomNumberInRange(0, 2)]; index2++; if(index2 == 6) index2 = 0; @@ -443,17 +447,14 @@ ResetLoadingScreenBar() NumberOfChunksLoaded = 0.0f; } -// TODO: compare with PS2 +//--MIAMI: done void LoadingScreen(const char *str1, const char *str2, const char *splashscreen) { CSprite2d *splash; #ifndef RANDOMSPLASH - if(CGame::frenchGame || CGame::germanGame || !CGame::nastyGame) - splashscreen = "mainsc2"; - else - splashscreen = "mainsc1"; + splashscreen = "LOADSC0"; #endif splash = LoadSplash(splashscreen); @@ -474,36 +475,50 @@ LoadingScreen(const char *str1, const char *str2, const char *splashscreen) if(str1){ NumberOfChunksLoaded += 1; +#ifndef RANDOMSPLASH float hpos = SCREEN_SCALE_X(40); - float length = SCREEN_WIDTH - SCREEN_SCALE_X(100); - float vpos = SCREEN_HEIGHT - SCREEN_SCALE_Y(13); - float height = SCREEN_SCALE_Y(7); - CSprite2d::DrawRect(CRect(hpos, vpos, hpos + length, vpos + height), CRGBA(40, 53, 68, 255)); + float length = SCREEN_WIDTH - SCREEN_SCALE_X(80); + float top = SCREEN_HEIGHT - SCREEN_SCALE_Y(14); + float bottom = top + SCREEN_SCALE_Y(5); +#else + float hpos = SCREEN_STRETCH_X(40); + float length = SCREEN_STRETCH_X(440); + // this is rather weird + float top = SCREEN_STRETCH_Y(407.4f - 7.0f/3.0f); + float bottom = SCREEN_STRETCH_Y(407.4f + 7.0f/3.0f); +#endif + + CSprite2d::DrawRect(CRect(hpos-1.0f, top-1.0f, hpos+length+1.0f, bottom+1.0f), CRGBA(40, 53, 68, 255)); + + CSprite2d::DrawRect(CRect(hpos, top, hpos+length, bottom), CRGBA(155, 50, 125, 255)); length *= NumberOfChunksLoaded/TOTALNUMCHUNKS; - CSprite2d::DrawRect(CRect(hpos, vpos, hpos + length, vpos + height), CRGBA(81, 106, 137, 255)); + CSprite2d::DrawRect(CRect(hpos, top, hpos+length, bottom), CRGBA(255, 150, 225, 255)); // this is done by the game but is unused + CFont::SetBackgroundOff(); CFont::SetScale(SCREEN_SCALE_X(2), SCREEN_SCALE_Y(2)); CFont::SetPropOn(); CFont::SetRightJustifyOn(); + CFont::SetDropShadowPosition(1); + CFont::SetDropColor(CRGBA(0, 0, 0, 255)); CFont::SetFontStyle(FONT_HEADING); #ifdef CHATTYSPLASH // my attempt static wchar tmpstr[80]; float yscale = SCREEN_SCALE_Y(0.9f); - vpos -= 45*yscale; + top -= 45*yscale; CFont::SetScale(SCREEN_SCALE_X(0.75f), yscale); CFont::SetPropOn(); CFont::SetRightJustifyOff(); CFont::SetFontStyle(FONT_BANK); CFont::SetColor(CRGBA(255, 255, 255, 255)); AsciiToUnicode(str1, tmpstr); - CFont::PrintString(hpos, vpos, tmpstr); - vpos += 22*yscale; + CFont::PrintString(hpos, top, tmpstr); + top += 22*yscale; AsciiToUnicode(str2, tmpstr); - CFont::PrintString(hpos, vpos, tmpstr); + CFont::PrintString(hpos, top, tmpstr); #endif } @@ -676,11 +691,13 @@ DisplayGameDebugText() { static bool bDisplayPosn = false; static bool bDisplayRate = false; + static bool bDisplayCheatStr = false; { SETTWEAKPATH("GameDebugText"); TWEAKBOOL(bDisplayPosn); TWEAKBOOL(bDisplayRate); + TWEAKBOOL(bDisplayCheatStr); } @@ -768,6 +785,26 @@ DisplayGameDebugText() CFont::SetColor(CRGBA(255, 108, 0, 255)); CFont::PrintString(40.0f, 40.0f, ustr); } + + if (bDisplayCheatStr) + { + sprintf(str, "%s", CPad::KeyBoardCheatString); + AsciiToUnicode(str, ustr); + + CFont::SetPropOff(); + CFont::SetBackgroundOff(); + CFont::SetScale(0.7f, 1.5f); + CFont::SetCentreOn(); + CFont::SetBackGroundOnlyTextOff(); + CFont::SetWrapx(640.0f); + CFont::SetFontStyle(FONT_HEADING); + + CFont::SetColor(CRGBA(0, 0, 0, 255)); + CFont::PrintString(SCREEN_SCALE_X(DEFAULT_SCREEN_WIDTH * 0.5f)+2.f, SCREEN_SCALE_FROM_BOTTOM(20.0f)+2.f, ustr); + + CFont::SetColor(CRGBA(255, 150, 225, 255)); + CFont::PrintString(SCREEN_SCALE_X(DEFAULT_SCREEN_WIDTH * 0.5f), SCREEN_SCALE_FROM_BOTTOM(20.0f), ustr); + } } #endif @@ -913,15 +950,12 @@ Render2dStuffAfterFade(void) CHud::DrawAfterFade(); CFont::DrawFonts(); + CCredits::Render(); } void Idle(void *arg) { -#ifdef ASPECT_RATIO_SCALE - CDraw::SetAspectRatio(CDraw::FindAspectRatio()); -#endif - CTimer::Update(); #ifdef TIMEBARS @@ -931,35 +965,6 @@ Idle(void *arg) CSprite2d::InitPerFrame(); CFont::InitPerFrame(); - // We're basically merging FrontendIdle and Idle (just like TheGame on PS2) -#ifdef PS2_SAVE_DIALOG - // Only exists on PC FrontendIdle, probably some PS2 bug fix - if (FrontEndMenuManager.m_bMenuActive) - CSprite2d::SetRecipNearClip(); - - if (FrontEndMenuManager.m_bGameNotLoaded) { - CPad::UpdatePads(); - FrontEndMenuManager.Process(); - } else { - CPointLights::InitPerFrame(); -#ifdef TIMEBARS - tbStartTimer(0, "CGame::Process"); -#endif - CGame::Process(); -#ifdef TIMEBARS - tbEndTimer("CGame::Process"); - tbStartTimer(0, "DMAudio.Service"); -#endif - DMAudio.Service(); - -#ifdef TIMEBARS - tbEndTimer("DMAudio.Service"); -#endif - } - - if (RsGlobal.quit) - return; -#else CPointLights::InitPerFrame(); #ifdef TIMEBARS tbStartTimer(0, "CGame::Process"); @@ -974,7 +979,6 @@ Idle(void *arg) #ifdef TIMEBARS tbEndTimer("DMAudio.Service"); -#endif #endif if(CGame::bDemoMode && CTimer::GetTimeInMilliseconds() > (3*60 + 30)*1000 && !CCutsceneMgr::IsCutsceneProcessing()){ @@ -991,17 +995,16 @@ Idle(void *arg) if(arg == nil) return; - if((!FrontEndMenuManager.m_bMenuActive || FrontEndMenuManager.m_bRenderGameInMenu) && + // m_bRenderGameInMenu is there in III PS2 but I don't know about VC PS2. + if((!FrontEndMenuManager.m_bMenuActive/* || FrontEndMenuManager.m_bRenderGameInMenu*/) && TheCamera.GetScreenFadeStatus() != FADE_2) { #ifdef GTA_PC - if (!FrontEndMenuManager.m_bRenderGameInMenu) { // This is from SA, but it's nice for windowed mode RwV2d pos; pos.x = SCREEN_WIDTH / 2.0f; pos.y = SCREEN_HEIGHT / 2.0f; RsMouseSetPos(&pos); - } #endif #ifdef TIMEBARS tbStartTimer(0, "CnstrRenderList"); @@ -1058,6 +1061,7 @@ Idle(void *arg) tbEndTimer("Render2dStuff"); #endif }else{ + CDraw::CalculateAspectRatio(); #ifdef ASPECT_RATIO_SCALE CameraSize(Scene.camera, nil, SCREEN_VIEWWINDOW, SCREEN_ASPECT_RATIO); #else @@ -1069,10 +1073,6 @@ Idle(void *arg) return; } -#ifdef PS2_SAVE_DIALOG - if (FrontEndMenuManager.m_bMenuActive) - DefinedState(); -#endif #ifdef TIMEBARS tbStartTimer(0, "RenderMenus"); #endif @@ -1090,7 +1090,7 @@ Idle(void *arg) #ifdef TIMEBARS tbEndTimer("Render2dStuff-Fade"); #endif - CCredits::Render(); + // CCredits::Render(); // They added it to function above and also forgot it here #ifdef TIMEBARS tbDisplay(); @@ -1105,10 +1105,7 @@ Idle(void *arg) void FrontendIdle(void) { -#ifdef ASPECT_RATIO_SCALE - CDraw::SetAspectRatio(CDraw::FindAspectRatio()); -#endif - + CDraw::CalculateAspectRatio(); CTimer::Update(); CSprite2d::SetRecipNearClip(); // this should be on InitialiseRenderWare according to PS2 asm. seems like a bug fix CSprite2d::InitPerFrame(); @@ -1119,11 +1116,7 @@ FrontendIdle(void) if(RsGlobal.quit) return; -#ifdef ASPECT_RATIO_SCALE CameraSize(Scene.camera, nil, SCREEN_VIEWWINDOW, SCREEN_ASPECT_RATIO); -#else - CameraSize(Scene.camera, nil, SCREEN_VIEWWINDOW, DEFAULT_ASPECT_RATIO); -#endif CVisibilityPlugins::SetRenderWareCamera(Scene.camera); RwCameraClear(Scene.camera, &gColourTop, rwCAMERACLEARZ); if(!RsCameraBeginUpdate(Scene.camera)) @@ -1133,7 +1126,7 @@ FrontendIdle(void) RenderMenus(); DoFade(); Render2dStuffAfterFade(); -// CFont::DrawFonts(); // redundant + CFont::DrawFonts(); DoRWStuffEndOfFrame(); } @@ -1149,10 +1142,10 @@ AppEventHandler(RsEvent event, void *param) { switch( event ) { - case rsINITIALISE: + case rsINITIALIZE: { CGame::InitialiseOnceBeforeRW(); - return RsInitialise() ? rsEVENTPROCESSED : rsEVENTERROR; + return RsInitialize() ? rsEVENTPROCESSED : rsEVENTERROR; } case rsCAMERASIZE: @@ -1164,7 +1157,7 @@ AppEventHandler(RsEvent event, void *param) return rsEVENTPROCESSED; } - case rsRWINITIALISE: + case rsRWINITIALIZE: { return Initialise3D(param) ? rsEVENTPROCESSED : rsEVENTERROR; } @@ -1204,11 +1197,7 @@ AppEventHandler(RsEvent event, void *param) case rsFRONTENDIDLE: { -#ifdef PS2_SAVE_DIALOG - Idle((void*)1); -#else FrontendIdle(); -#endif return rsEVENTPROCESSED; } @@ -1243,9 +1232,8 @@ TheModelViewer(void) #if (defined(GTA_PS2) || defined(GTA_XBOX)) //TODO #else -#ifdef ASPECT_RATIO_SCALE - CDraw::SetAspectRatio(CDraw::FindAspectRatio()); -#endif + + CDraw::CalculateAspectRatio(); CAnimViewer::Update(); CTimer::Update(); SetLightsWithTimeOfDayColour(Scene.world); @@ -1294,9 +1282,9 @@ void TheGame(void) strcpy(TheMemoryCard.LoadFileName, TheMemoryCard.field37); TheMemoryCard.b_FoundRecentSavedGameWantToLoad = true; - if (CMenuManager::m_PrefsLanguage != TheMemoryCard.GetLanguageToLoad()) + if (FrontEndMenuManager.m_PrefsLanguage != TheMemoryCard.GetLanguageToLoad()) { - CMenuManager::m_PrefsLanguage = TheMemoryCard.GetLanguageToLoad(); + FrontEndMenuManager.m_PrefsLanguage = TheMemoryCard.GetLanguageToLoad(); TheText.Unload(); TheText.Load(); } @@ -1370,7 +1358,8 @@ void TheGame(void) gMainHeap.PushMemId(_TODOCONST(15)); #endif - if (!FrontEndMenuManager.m_bMenuActive || FrontEndMenuManager.m_bRenderGameInMenu == true && TheCamera.GetScreenFadeStatus() != FADE_2 ) + // m_bRenderGameInMenu is there in III PS2 but I don't know about VC PS2. + if (!FrontEndMenuManager.m_bMenuActive || /*FrontEndMenuManager.m_bRenderGameInMenu == true && */TheCamera.GetScreenFadeStatus() != FADE_2 ) { #ifdef GTA_PS2 gMainHeap.PushMemId(_TODOCONST(11)); @@ -1577,30 +1566,30 @@ void SystemInit() CGame::frenchGame = false; CGame::germanGame = false; CGame::nastyGame = true; - CMenuManager::m_PrefsAllowNastyGame = true; + FrontEndMenuManager.m_PrefsAllowNastyGame = true; #ifdef GTA_PS2 int32 lang = sceScfGetLanguage(); if ( lang == SCE_ITALIAN_LANGUAGE ) - CMenuManager::m_PrefsLanguage = LANGUAGE_ITALIAN; + FrontEndMenuManager.m_PrefsLanguage = LANGUAGE_ITALIAN; else if ( lang == SCE_SPANISH_LANGUAGE ) - CMenuManager::m_PrefsLanguage = LANGUAGE_SPANISH; + FrontEndMenuManager.m_PrefsLanguage = LANGUAGE_SPANISH; else if ( lang == SCE_GERMAN_LANGUAGE ) { CGame::germanGame = true; CGame::nastyGame = false; - CMenuManager::m_PrefsAllowNastyGame = false; - CMenuManager::m_PrefsLanguage = LANGUAGE_GERMAN; + FrontEndMenuManager.m_PrefsAllowNastyGame = false; + FrontEndMenuManager.m_PrefsLanguage = LANGUAGE_GERMAN; } else if ( lang == SCE_FRENCH_LANGUAGE ) { CGame::frenchGame = true; CGame::nastyGame = false; - CMenuManager::m_PrefsAllowNastyGame = false; - CMenuManager::m_PrefsLanguage = LANGUAGE_FRENCH; + FrontEndMenuManager.m_PrefsAllowNastyGame = false; + FrontEndMenuManager.m_PrefsLanguage = LANGUAGE_FRENCH; } else - CMenuManager::m_PrefsLanguage = LANGUAGE_AMERICAN; + FrontEndMenuManager.m_PrefsLanguage = LANGUAGE_AMERICAN; FrontEndMenuManager.InitialiseMenuContentsAfterLoadingGame(); #else diff --git a/src/core/re3.cpp b/src/core/re3.cpp index 0e62f3a5..54077e6f 100644 --- a/src/core/re3.cpp +++ b/src/core/re3.cpp @@ -69,7 +69,7 @@ mysrand(unsigned int seed) #ifdef DEBUGMENU void WeaponCheat(); void HealthCheat(); -void TankCheat(); +void VehicleCheat(bool something, int model); void BlowUpCarsCheat(); void ChangePlayerCheat(); void MayhemCheat(); @@ -160,6 +160,13 @@ TeleportToWaypoint(void) } #endif +static void +SwitchCarCollision(void) +{ + if (FindPlayerVehicle() && FindPlayerVehicle()->IsCar()) + FindPlayerVehicle()->bUsesCollision = !FindPlayerVehicle()->bUsesCollision; +} + static int engineStatus; static void SetEngineStatus(void) @@ -273,7 +280,7 @@ DebugMenuPopulate(void) { if(1){ static const char *weathers[] = { - "Sunny", "Cloudy", "Rainy", "Foggy" + "Sunny", "Cloudy", "Rainy", "Foggy", "Extrasunny", "Stormy" }; DebugMenuEntry *e; e = DebugMenuAddVar("Time & Weather", "Current Hour", &CClock::GetHoursRef(), nil, 1, 0, 23, nil); @@ -281,9 +288,9 @@ DebugMenuPopulate(void) e = DebugMenuAddVar("Time & Weather", "Current Minute", &CClock::GetMinutesRef(), [](){ CWeather::InterpolationValue = CClock::GetMinutes()/60.0f; }, 1, 0, 59, nil); DebugMenuEntrySetWrap(e, true); - e = DebugMenuAddVar("Time & Weather", "Old Weather", (int16*)&CWeather::OldWeatherType, nil, 1, 0, 3, weathers); + e = DebugMenuAddVar("Time & Weather", "Old Weather", (int16*)&CWeather::OldWeatherType, nil, 1, 0, 5, weathers); DebugMenuEntrySetWrap(e, true); - e = DebugMenuAddVar("Time & Weather", "New Weather", (int16*)&CWeather::NewWeatherType, nil, 1, 0, 3, weathers); + e = DebugMenuAddVar("Time & Weather", "New Weather", (int16*)&CWeather::NewWeatherType, nil, 1, 0, 5, weathers); DebugMenuEntrySetWrap(e, true); DebugMenuAddVar("Time & Weather", "Wind", (float*)&CWeather::Wind, nil, 0.1f, 0.0f, 1.0f); DebugMenuAddVar("Time & Weather", "Time scale", (float*)&CTimer::GetTimeScale(), nil, 0.1f, 0.0f, 10.0f); @@ -293,7 +300,7 @@ DebugMenuPopulate(void) DebugMenuAddCmd("Cheats", "Health", HealthCheat); DebugMenuAddCmd("Cheats", "Wanted level up", WantedLevelUpCheat); DebugMenuAddCmd("Cheats", "Wanted level down", WantedLevelDownCheat); - DebugMenuAddCmd("Cheats", "Tank", TankCheat); + DebugMenuAddCmd("Cheats", "Tank", []() { VehicleCheat(true, MI_TAXI); }); DebugMenuAddCmd("Cheats", "Blow up cars", BlowUpCarsCheat); DebugMenuAddCmd("Cheats", "Change player", ChangePlayerCheat); DebugMenuAddCmd("Cheats", "Mayhem", MayhemCheat); @@ -337,7 +344,11 @@ DebugMenuPopulate(void) DebugMenuAddCmd("Spawn", "Spawn Banshee", [](){ SpawnCar(MI_BANSHEE); }); DebugMenuAddCmd("Spawn", "Spawn Cuban", [](){ SpawnCar(MI_CUBAN); }); DebugMenuAddCmd("Spawn", "Spawn Voodoo", [](){ SpawnCar(MI_VOODOO); }); + DebugMenuAddCmd("Spawn", "Spawn Maverick", [](){ SpawnCar(MI_MAVERICK); }); + DebugMenuAddCmd("Spawn", "Spawn VCN Maverick", [](){ SpawnCar(MI_VCNMAV); }); DebugMenuAddCmd("Spawn", "Spawn Sparrow", [](){ SpawnCar(MI_SPARROW); }); + DebugMenuAddCmd("Spawn", "Spawn Sea Sparrow", [](){ SpawnCar(MI_SEASPAR); }); + DebugMenuAddCmd("Spawn", "Spawn Hunter", [](){ SpawnCar(MI_HUNTER); }); DebugMenuAddCmd("Spawn", "Spawn Rhino", [](){ SpawnCar(MI_RHINO); }); DebugMenuAddCmd("Spawn", "Spawn Firetruck", [](){ SpawnCar(MI_FIRETRUCK); }); DebugMenuAddCmd("Spawn", "Spawn Predator", [](){ SpawnCar(MI_PREDATOR); }); @@ -365,6 +376,7 @@ DebugMenuPopulate(void) #ifdef MENU_MAP DebugMenuAddCmd("Debug", "Teleport to map waypoint", TeleportToWaypoint); #endif + DebugMenuAddCmd("Debug", "Switch car collision", SwitchCarCollision); DebugMenuAddVar("Debug", "Engine Status", &engineStatus, nil, 1, 0, 226, nil); DebugMenuAddCmd("Debug", "Set Engine Status", SetEngineStatus); DebugMenuAddCmd("Debug", "Fix Car", FixCar); @@ -385,6 +397,13 @@ DebugMenuPopulate(void) DebugMenuAddCmd("Debug", "Start Credits", CCredits::Start); DebugMenuAddCmd("Debug", "Stop Credits", CCredits::Stop); +#ifdef RELOADABLES + DebugMenuAddCmd("Reload", "HUD.TXD", CHud::ReloadTXD); + DebugMenuAddCmd("Reload", "FONTS.TXD", NULL); + DebugMenuAddCmd("Reload", "FRONTEN1.TXD", NULL); + DebugMenuAddCmd("Reload", "FRONTEN2.TXD", NULL); +#endif + extern bool PrintDebugCode; extern int16 DebugCamMode; DebugMenuAddVarBool8("Cam", "Use mouse Cam", &CCamera::m_bUseMouse3rdPerson, nil); diff --git a/src/entities/Building.cpp b/src/entities/Building.cpp index 3c096636..3217e684 100644 --- a/src/entities/Building.cpp +++ b/src/entities/Building.cpp @@ -20,3 +20,25 @@ CBuilding::ReplaceWithNewModel(int32 id) if(m_level == LEVEL_NONE || m_level == CGame::currLevel) CStreaming::RequestModel(id, STREAMFLAGS_DONT_REMOVE); } + +bool +IsBuildingPointerValid(CBuilding* pBuilding) +{ + if (!pBuilding) + return false; + if (pBuilding->GetIsATreadable()) { + int index = CPools::GetTreadablePool()->GetJustIndex((CTreadable*)pBuilding); +#ifdef FIX_BUGS + return index >= 0 && index < CPools::GetTreadablePool()->GetSize(); +#else + return index >= 0 && index <= CPools::GetTreadablePool()->GetSize(); +#endif + } else { + int index = CPools::GetBuildingPool()->GetJustIndex(pBuilding); +#ifdef FIX_BUGS + return index >= 0 && index < CPools::GetBuildingPool()->GetSize(); +#else + return index >= 0 && index <= CPools::GetBuildingPool()->GetSize(); +#endif + } +} diff --git a/src/entities/Building.h b/src/entities/Building.h index 29608c10..2c2dfb1f 100644 --- a/src/entities/Building.h +++ b/src/entities/Building.h @@ -16,3 +16,5 @@ public: virtual bool GetIsATreadable(void) { return false; } }; + +bool IsBuildingPointerValid(CBuilding*); diff --git a/src/entities/Dummy.cpp b/src/entities/Dummy.cpp index 8a4bfd5f..92b69761 100644 --- a/src/entities/Dummy.cpp +++ b/src/entities/Dummy.cpp @@ -50,3 +50,18 @@ CDummy::Remove(void) m_entryInfoList.DeleteNode(node); } } + +bool +IsDummyPointerValid(CDummy* pDummy) +{ + if (!pDummy) + return false; + int index = CPools::GetDummyPool()->GetJustIndex(pDummy); +#ifdef FIX_BUGS + if (index < 0 || index >= CPools::GetDummyPool()->GetSize()) +#else + if (index < 0 || index > CPools::GetDummyPool()->GetSize()) +#endif + return false; + return pDummy->m_entryInfoList.first; +} diff --git a/src/entities/Dummy.h b/src/entities/Dummy.h index 7998a748..84b1ce1a 100644 --- a/src/entities/Dummy.h +++ b/src/entities/Dummy.h @@ -15,3 +15,5 @@ public: static void *operator new(size_t); static void operator delete(void*, size_t); }; + +bool IsDummyPointerValid(CDummy* pDummy); diff --git a/src/entities/Entity.cpp b/src/entities/Entity.cpp index 6f8ebcb4..68486a3c 100644 --- a/src/entities/Entity.cpp +++ b/src/entities/Entity.cpp @@ -28,6 +28,11 @@ #include "Bones.h" #include "Debug.h" #include "Renderer.h" +#include "Ped.h" +#include "Dummy.h" +#include "WindModifiers.h" + +//--MIAMI: file almost done (see TODO) int gBuildings; @@ -78,7 +83,7 @@ CEntity::CEntity(void) bIsStaticWaitingForCollision = false; m_flagE10 = false; bUnderwater = false; - m_flagE40 = false; + bHasPreRenderEffects = false; m_scanCode = 0; m_modelIndex = -1; @@ -274,6 +279,21 @@ CEntity::Remove(void) } } +void +CEntity::SetModelIndex(uint32 id) +{ + m_modelIndex = id; + bHasPreRenderEffects = HasPreRenderEffects(); + CreateRwObject(); +} + +void +CEntity::SetModelIndexNoCreate(uint32 id) +{ + m_modelIndex = id; + bHasPreRenderEffects = HasPreRenderEffects(); +} + void CEntity::CreateRwObject(void) { @@ -304,10 +324,8 @@ CEntity::DeleteRwObject(void) RpAtomicDestroy((RpAtomic*)m_rwObject); RwFrameDestroy(f); }else if(RwObjectGetType(m_rwObject) == rpCLUMP){ -#ifdef PED_SKIN if(IsClumpSkinned((RpClump*)m_rwObject)) RpClumpForAllAtomics((RpClump*)m_rwObject, AtomicRemoveAnimFromSkinCB, nil); -#endif RpClumpDestroy((RpClump*)m_rwObject); } m_rwObject = nil; @@ -328,7 +346,6 @@ CEntity::UpdateRwFrame(void) } } -//--MIAMI: done void CEntity::SetupBigBuilding(void) { @@ -368,19 +385,39 @@ CEntity::GetBoundRect(void) return rect; } +bool +CEntity::HasPreRenderEffects(void) +{ + return IsTreeModel(GetModelIndex()) || + GetModelIndex() == MI_COLLECTABLE1 || + GetModelIndex() == MI_MONEY || + GetModelIndex() == MI_CARMINE || + GetModelIndex() == MI_NAUTICALMINE || + GetModelIndex() == MI_BRIEFCASE || + GetModelIndex() == MI_GRENADE || + GetModelIndex() == MI_MOLOTOV || + GetModelIndex() == MI_MISSILE || + GetModelIndex() == MI_BEACHBALL || + IsGlass(GetModelIndex()) || + IsObject() && ((CObject*)this)->bIsPickup || + IsLightWithPreRenderEffects(GetModelIndex()); +} + void CEntity::PreRender(void) { + if (CModelInfo::GetModelInfo(GetModelIndex())->GetNum2dEffects() != 0) + ProcessLightsForEntity(); + + if(!bHasPreRenderEffects) + return; + switch(m_type){ case ENTITY_TYPE_BUILDING: - if(GetModelIndex() == MI_RAILTRACKS){ - CShadows::StoreShadowForPole(this, 0.0f, -10.949f, 5.0f, 8.0f, 1.0f, 0); - CShadows::StoreShadowForPole(this, 0.0f, 10.949f, 5.0f, 8.0f, 1.0f, 1); - }else if(IsTreeModel(GetModelIndex())){ - CShadows::StoreShadowForTree(this); + if(IsTreeModel(GetModelIndex())){ + float dist = (TheCamera.GetPosition() - GetPosition()).Magnitude2D(); + CObject::fDistToNearestTree = Min(CObject::fDistToNearestTree, dist); ModifyMatrixForTreeInWind(); - }else if(IsBannerModel(GetModelIndex())){ - ModifyMatrixForBannerInWind(); } break; case ENTITY_TYPE_OBJECT: @@ -400,22 +437,6 @@ CEntity::PreRender(void) GetMatrix().UpdateRW(); UpdateRwFrame(); } - }else if(IsPickupModel(GetModelIndex())){ - if(((CObject*)this)->bIsPickup){ - CPickups::DoPickUpEffects(this); - GetMatrix().UpdateRW(); - UpdateRwFrame(); - }else if(GetModelIndex() == MI_GRENADE){ - CMotionBlurStreaks::RegisterStreak((uintptr)this, - 100, 100, 100, - GetPosition() - 0.07f*TheCamera.GetRight(), - GetPosition() + 0.07f*TheCamera.GetRight()); - }else if(GetModelIndex() == MI_MOLOTOV){ - CMotionBlurStreaks::RegisterStreak((uintptr)this, - 0, 100, 0, - GetPosition() - 0.07f*TheCamera.GetRight(), - GetPosition() + 0.07f*TheCamera.GetRight()); - } }else if(GetModelIndex() == MI_MISSILE){ CVector pos = GetPosition(); float flicker = (CGeneral::GetRandomNumber() & 0xF)/(float)0x10; @@ -438,12 +459,44 @@ CEntity::PreRender(void) CCoronas::LOSCHECK_OFF, CCoronas::STREAK_OFF, 0.0f); }else if(IsGlass(GetModelIndex())){ PreRenderForGlassWindow(); + }else if (((CObject*)this)->bIsPickup) { + CPickups::DoPickUpEffects(this); + GetMatrix().UpdateRW(); + UpdateRwFrame(); + } else if (GetModelIndex() == MI_GRENADE) { + CMotionBlurStreaks::RegisterStreak((uintptr)this, + 100, 100, 100, + GetPosition() - 0.07f * TheCamera.GetRight(), + GetPosition() + 0.07f * TheCamera.GetRight()); + } else if (GetModelIndex() == MI_MOLOTOV) { + CMotionBlurStreaks::RegisterStreak((uintptr)this, + 0, 100, 0, + GetPosition() - 0.07f * TheCamera.GetRight(), + GetPosition() + 0.07f * TheCamera.GetRight()); + }else if(GetModelIndex() == MI_BEACHBALL){ + CVector pos = GetPosition(); + CShadows::StoreShadowToBeRendered(SHADOWTYPE_DARK, + gpShadowPedTex, &pos, + 0.4f, 0.0f, 0.0f, -0.4f, + CTimeCycle::GetShadowStrength(), + CTimeCycle::GetShadowStrength(), + CTimeCycle::GetShadowStrength(), + CTimeCycle::GetShadowStrength(), + 20.0f, false, 1.0f); } // fall through case ENTITY_TYPE_DUMMY: if(GetModelIndex() == MI_TRAFFICLIGHTS){ CTrafficLights::DisplayActualLight(this); CShadows::StoreShadowForPole(this, 2.957f, 0.147f, 0.0f, 16.0f, 0.4f, 0); + }else if(GetModelIndex() == MI_TRAFFICLIGHTS_VERTICAL){ + CTrafficLights::DisplayActualLight(this); + }else if(GetModelIndex() == MI_TRAFFICLIGHTS_MIAMI){ + CTrafficLights::DisplayActualLight(this); + CShadows::StoreShadowForPole(this, 4.819f, 1.315f, 0.0f, 16.0f, 0.4f, 0); + }else if(GetModelIndex() == MI_TRAFFICLIGHTS_TWOVERTICAL){ + CTrafficLights::DisplayActualLight(this); + CShadows::StoreShadowForPole(this, 7.503f, 0.0f, 0.0f, 16.0f, 0.4f, 0); }else if(GetModelIndex() == MI_SINGLESTREETLIGHTS1) CShadows::StoreShadowForPole(this, 0.744f, 0.0f, 0.0f, 16.0f, 0.4f, 0); else if(GetModelIndex() == MI_SINGLESTREETLIGHTS2) @@ -452,19 +505,15 @@ CEntity::PreRender(void) CShadows::StoreShadowForPole(this, 1.143f, 0.145f, 0.0f, 16.0f, 0.4f, 0); else if(GetModelIndex() == MI_DOUBLESTREETLIGHTS) CShadows::StoreShadowForPole(this, 0.0f, -0.048f, 0.0f, 16.0f, 0.4f, 0); - else if(GetModelIndex() == MI_STREETLAMP1 || - GetModelIndex() == MI_STREETLAMP2) - CShadows::StoreShadowForPole(this, 0.0f, 0.0f, 0.0f, 16.0f, 0.4f, 0); break; } - - if (CModelInfo::GetModelInfo(GetModelIndex())->GetNum2dEffects() != 0) - ProcessLightsForEntity(); } void CEntity::PreRenderForGlassWindow(void) { + if(((CSimpleModelInfo*)CModelInfo::GetModelInfo(m_modelIndex))->m_isArtistGlass) + return; CGlass::AskForObjectToBeRenderedInGlass(this); bIsVisible = false; } @@ -485,8 +534,6 @@ CEntity::Render(void) bool CEntity::SetupLighting(void) { - DeActivateDirectional(); - SetAmbientColours(); return false; } @@ -572,13 +619,12 @@ CEntity::PruneReferences(void) } } -#ifdef PED_SKIN void CEntity::UpdateRpHAnim(void) { - RpHAnimHierarchy *hier = GetAnimHierarchyFromSkinClump(GetClump()); - RpHAnimHierarchyUpdateMatrices(hier); - + if(IsClumpSkinned(GetClump())){ + RpHAnimHierarchy *hier = GetAnimHierarchyFromSkinClump(GetClump()); + RpHAnimHierarchyUpdateMatrices(hier); #if 0 int i; char buf[256]; @@ -607,8 +653,8 @@ CEntity::UpdateRpHAnim(void) void RenderSkeleton(RpHAnimHierarchy *hier); RenderSkeleton(hier); #endif + } } -#endif void CEntity::AddSteamsFromGround(CVector *unused) @@ -640,6 +686,15 @@ CEntity::AddSteamsFromGround(CVector *unused) case 4: CParticleObject::AddObject(POBJECT_DARK_SMOKE, pos, effect->particle.dir, effect->particle.scale, false); break; +// TODO(MIAMI): enable this once we have the particle objects +/* + case 5: + CParticleObject::AddObject(POBJECT_WATER_FOUNTAIN_VERT, pos, effect->particle.dir, effect->particle.scale, false); + break; + case 6: + CParticleObject::AddObject(POBJECT_WATER_FOUNTAIN_HORIZ, pos, effect->particle.dir, effect->particle.scale, false); + break; +*/ } } } @@ -664,80 +719,66 @@ CEntity::ProcessLightsForEntity(void) for(i = 0; i < n; i++, flashTimer1 += 0x80, flashTimer2 += 0x100, flashTimer3 += 0x200){ effect = CModelInfo::GetModelInfo(GetModelIndex())->Get2dEffect(i); - if(effect->type != EFFECT_LIGHT) - continue; + switch(effect->type){ + case EFFECT_LIGHT: + pos = GetMatrix() * effect->pos; - pos = GetMatrix() * effect->pos; - - lightOn = false; - lightFlickering = false; - switch(effect->light.lightType){ - case LIGHT_ON: - lightOn = true; - break; - case LIGHT_ON_NIGHT: - if(CClock::GetHours() > 18 || CClock::GetHours() < 7) + lightOn = false; + lightFlickering = false; + switch(effect->light.lightType){ + case LIGHT_ON: lightOn = true; - break; - case LIGHT_FLICKER: - if((CTimer::GetTimeInMilliseconds() ^ m_randomSeed) & 0x60) - lightOn = true; - else - lightFlickering = true; - if((CTimer::GetTimeInMilliseconds()>>11 ^ m_randomSeed) & 3) - lightOn = true; - break; - case LIGHT_FLICKER_NIGHT: - if(CClock::GetHours() > 18 || CClock::GetHours() < 7){ + break; + case LIGHT_ON_NIGHT: + if(CClock::GetHours() > 18 || CClock::GetHours() < 7) + lightOn = true; + break; + case LIGHT_FLICKER: if((CTimer::GetTimeInMilliseconds() ^ m_randomSeed) & 0x60) lightOn = true; else lightFlickering = true; if((CTimer::GetTimeInMilliseconds()>>11 ^ m_randomSeed) & 3) lightOn = true; - } - break; - case LIGHT_FLASH1: - if((CTimer::GetTimeInMilliseconds() + flashTimer1) & 0x200) - lightOn = true; - break; - case LIGHT_FLASH1_NIGHT: - if(CClock::GetHours() > 18 || CClock::GetHours() < 7) + break; + case LIGHT_FLICKER_NIGHT: + if(CClock::GetHours() > 18 || CClock::GetHours() < 7 || CWeather::WetRoads > 0.5f){ + if((CTimer::GetTimeInMilliseconds() ^ m_randomSeed) & 0x60) + lightOn = true; + else + lightFlickering = true; + if((CTimer::GetTimeInMilliseconds()>>11 ^ m_randomSeed) & 3) + lightOn = true; + } + break; + case LIGHT_FLASH1: if((CTimer::GetTimeInMilliseconds() + flashTimer1) & 0x200) lightOn = true; - break; - case LIGHT_FLASH2: - if((CTimer::GetTimeInMilliseconds() + flashTimer2) & 0x400) - lightOn = true; - break; - case LIGHT_FLASH2_NIGHT: - if(CClock::GetHours() > 18 || CClock::GetHours() < 7) + break; + case LIGHT_FLASH1_NIGHT: + if(CClock::GetHours() > 18 || CClock::GetHours() < 7) + if((CTimer::GetTimeInMilliseconds() + flashTimer1) & 0x200) + lightOn = true; + break; + case LIGHT_FLASH2: if((CTimer::GetTimeInMilliseconds() + flashTimer2) & 0x400) lightOn = true; - break; - case LIGHT_FLASH3: - if((CTimer::GetTimeInMilliseconds() + flashTimer3) & 0x800) - lightOn = true; - break; - case LIGHT_FLASH3_NIGHT: - if(CClock::GetHours() > 18 || CClock::GetHours() < 7) + break; + case LIGHT_FLASH2_NIGHT: + if(CClock::GetHours() > 18 || CClock::GetHours() < 7) + if((CTimer::GetTimeInMilliseconds() + flashTimer2) & 0x400) + lightOn = true; + break; + case LIGHT_FLASH3: if((CTimer::GetTimeInMilliseconds() + flashTimer3) & 0x800) lightOn = true; - break; - case LIGHT_RANDOM_FLICKER: - if(m_randomSeed > 16) - lightOn = true; - else{ - if((CTimer::GetTimeInMilliseconds() ^ m_randomSeed*8) & 0x60) - lightOn = true; - else - lightFlickering = true; - if((CTimer::GetTimeInMilliseconds()>>11 ^ m_randomSeed*8) & 3) - lightOn = true; - } - break; - case LIGHT_RANDOM_FLICKER_NIGHT: - if(CClock::GetHours() > 18 || CClock::GetHours() < 7){ + break; + case LIGHT_FLASH3_NIGHT: + if(CClock::GetHours() > 18 || CClock::GetHours() < 7) + if((CTimer::GetTimeInMilliseconds() + flashTimer3) & 0x800) + lightOn = true; + break; + case LIGHT_RANDOM_FLICKER: if(m_randomSeed > 16) lightOn = true; else{ @@ -748,85 +789,143 @@ CEntity::ProcessLightsForEntity(void) if((CTimer::GetTimeInMilliseconds()>>11 ^ m_randomSeed*8) & 3) lightOn = true; } + break; + case LIGHT_RANDOM_FLICKER_NIGHT: + if(CClock::GetHours() > 18 || CClock::GetHours() < 7){ + if(m_randomSeed > 16) + lightOn = true; + else{ + if((CTimer::GetTimeInMilliseconds() ^ m_randomSeed*8) & 0x60) + lightOn = true; + else + lightFlickering = true; + if((CTimer::GetTimeInMilliseconds()>>11 ^ m_randomSeed*8) & 3) + lightOn = true; + } + } + break; + case LIGHT_BRIDGE_FLASH1: + if(CBridge::ShouldLightsBeFlashing() && CTimer::GetTimeInMilliseconds() & 0x200) + lightOn = true; + break; + case LIGHT_BRIDGE_FLASH2: + if(CBridge::ShouldLightsBeFlashing() && (CTimer::GetTimeInMilliseconds() & 0x1FF) < 60) + lightOn = true; + break; + } + + if(effect->light.flags & LIGHTFLAG_HIDE_OBJECT){ + if(lightOn) + bDoNotRender = false; + else + bDoNotRender = true; + return; + } + + // Corona + if(lightOn) + CCoronas::RegisterCorona((uintptr)this + i, + effect->col.r, effect->col.g, effect->col.b, 255, + pos, effect->light.size, effect->light.dist, + effect->light.corona, effect->light.flareType, effect->light.roadReflection, + effect->light.flags&LIGHTFLAG_LOSCHECK, CCoronas::STREAK_OFF, 0.0f, + !!(effect->light.flags&LIGHTFLAG_LONG_DIST)); + else if(lightFlickering) + CCoronas::RegisterCorona((uintptr)this + i, + 0, 0, 0, 255, + pos, effect->light.size, effect->light.dist, + effect->light.corona, effect->light.flareType, effect->light.roadReflection, + effect->light.flags&LIGHTFLAG_LOSCHECK, CCoronas::STREAK_OFF, 0.0f, + !!(effect->light.flags&LIGHTFLAG_LONG_DIST)); + + // Pointlight + bool alreadyProcessedFog; + alreadyProcessedFog = false; + if(effect->light.range != 0.0f && lightOn){ + if(effect->col.r == 0 && effect->col.g == 0 && effect->col.b == 0){ + CPointLights::AddLight(CPointLights::LIGHT_POINT, + pos, CVector(0.0f, 0.0f, 0.0f), + effect->light.range, + 0.0f, 0.0f, 0.0f, + CPointLights::FOG_NONE, true); + }else{ + CPointLights::AddLight(CPointLights::LIGHT_POINT, + pos, CVector(0.0f, 0.0f, 0.0f), + effect->light.range, + effect->col.r*CTimeCycle::GetSpriteBrightness()/255.0f, + effect->col.g*CTimeCycle::GetSpriteBrightness()/255.0f, + effect->col.b*CTimeCycle::GetSpriteBrightness()/255.0f, + (effect->light.flags & LIGHTFLAG_FOG) >> 1, + true); + alreadyProcessedFog = true; + } + } + + if(!alreadyProcessedFog){ + if(effect->light.flags & LIGHTFLAG_FOG_ALWAYS){ + CPointLights::AddLight(CPointLights::LIGHT_FOGONLY_ALWAYS, + pos, CVector(0.0f, 0.0f, 0.0f), + 0.0f, + effect->col.r/255.0f, effect->col.g/255.0f, effect->col.b/255.0f, + CPointLights::FOG_ALWAYS, true); + }else if(effect->light.flags & LIGHTFLAG_FOG_NORMAL && lightOn && effect->light.range == 0.0f){ + CPointLights::AddLight(CPointLights::LIGHT_FOGONLY, + pos, CVector(0.0f, 0.0f, 0.0f), + 0.0f, + effect->col.r/255.0f, effect->col.g/255.0f, effect->col.b/255.0f, + CPointLights::FOG_NORMAL, true); + } + } + + // Light shadow + if(effect->light.shadowRange != 0.0f){ + if(lightOn){ + CShadows::StoreStaticShadow((uintptr)this + i, SHADOWTYPE_ADDITIVE, + effect->light.shadow, &pos, + effect->light.shadowRange, 0.0f, + 0.0f, -effect->light.shadowRange, + 128, + effect->col.r*CTimeCycle::GetSpriteBrightness()*effect->light.shadowIntensity/255.0f, + effect->col.g*CTimeCycle::GetSpriteBrightness()*effect->light.shadowIntensity/255.0f, + effect->col.b*CTimeCycle::GetSpriteBrightness()*effect->light.shadowIntensity/255.0f, + 15.0f, 1.0f, 40.0f, false, 0.0f); + }else if(lightFlickering){ + CShadows::StoreStaticShadow((uintptr)this + i, SHADOWTYPE_ADDITIVE, + effect->light.shadow, &pos, + effect->light.shadowRange, 0.0f, + 0.0f, -effect->light.shadowRange, + 0, 0.0f, 0.0f, 0.0f, + 15.0f, 1.0f, 40.0f, false, 0.0f); + } } break; - case LIGHT_BRIDGE_FLASH1: - if(CBridge::ShouldLightsBeFlashing() && CTimer::GetTimeInMilliseconds() & 0x200) - lightOn = true; - break; - case LIGHT_BRIDGE_FLASH2: - if(CBridge::ShouldLightsBeFlashing() && (CTimer::GetTimeInMilliseconds() & 0x1FF) < 60) - lightOn = true; - break; - } - // Corona - if(lightOn) - CCoronas::RegisterCorona((uintptr)this + i, - effect->col.r, effect->col.g, effect->col.b, 255, - pos, effect->light.size, effect->light.dist, - effect->light.corona, effect->light.flareType, effect->light.roadReflection, - effect->light.flags&LIGHTFLAG_LOSCHECK, CCoronas::STREAK_OFF, 0.0f); - else if(lightFlickering) - CCoronas::RegisterCorona((uintptr)this + i, - 0, 0, 0, 255, - pos, effect->light.size, effect->light.dist, - effect->light.corona, effect->light.flareType, effect->light.roadReflection, - effect->light.flags&LIGHTFLAG_LOSCHECK, CCoronas::STREAK_OFF, 0.0f); - - // Pointlight - if(effect->light.flags & LIGHTFLAG_FOG_ALWAYS){ - CPointLights::AddLight(CPointLights::LIGHT_FOGONLY_ALWAYS, - pos, CVector(0.0f, 0.0f, 0.0f), - effect->light.range, - effect->col.r/255.0f, effect->col.g/255.0f, effect->col.b/255.0f, - CPointLights::FOG_ALWAYS, true); - }else if(effect->light.flags & LIGHTFLAG_FOG_NORMAL && lightOn && effect->light.range == 0.0f){ - CPointLights::AddLight(CPointLights::LIGHT_FOGONLY, - pos, CVector(0.0f, 0.0f, 0.0f), - effect->light.range, - effect->col.r/255.0f, effect->col.g/255.0f, effect->col.b/255.0f, - CPointLights::FOG_NORMAL, true); - }else if(lightOn && effect->light.range != 0.0f){ - if(effect->col.r == 0 && effect->col.g == 0 && effect->col.b == 0){ - CPointLights::AddLight(CPointLights::LIGHT_POINT, - pos, CVector(0.0f, 0.0f, 0.0f), - effect->light.range, - 0.0f, 0.0f, 0.0f, - CPointLights::FOG_NONE, true); - }else{ - CPointLights::AddLight(CPointLights::LIGHT_POINT, - pos, CVector(0.0f, 0.0f, 0.0f), - effect->light.range, - effect->col.r*CTimeCycle::GetSpriteBrightness()/255.0f, - effect->col.g*CTimeCycle::GetSpriteBrightness()/255.0f, - effect->col.b*CTimeCycle::GetSpriteBrightness()/255.0f, - // half-useless because LIGHTFLAG_FOG_ALWAYS can't be on - (effect->light.flags & LIGHTFLAG_FOG) >> 1, - true); - } - } - - // Light shadow - if(effect->light.shadowRange != 0.0f){ - if(lightOn){ - CShadows::StoreStaticShadow((uintptr)this + i, SHADOWTYPE_ADDITIVE, - effect->light.shadow, &pos, - effect->light.shadowRange, 0.0f, - 0.0f, -effect->light.shadowRange, - 128, - effect->col.r*CTimeCycle::GetSpriteBrightness()*effect->light.shadowIntensity/255.0f, - effect->col.g*CTimeCycle::GetSpriteBrightness()*effect->light.shadowIntensity/255.0f, - effect->col.b*CTimeCycle::GetSpriteBrightness()*effect->light.shadowIntensity/255.0f, - 15.0f, 1.0f, 40.0f, false, 0.0f); - }else if(lightFlickering){ - CShadows::StoreStaticShadow((uintptr)this + i, SHADOWTYPE_ADDITIVE, - effect->light.shadow, &pos, - effect->light.shadowRange, 0.0f, - 0.0f, -effect->light.shadowRange, - 0, 0.0f, 0.0f, 0.0f, - 15.0f, 1.0f, 40.0f, false, 0.0f); + case EFFECT_SUNGLARE: + if(CWeather::SunGlare >= 0.0f){ + CVector pos = GetMatrix() * effect->pos; + CVector glareDir = pos - GetPosition(); + glareDir.Normalise(); + CVector camDir = TheCamera.GetPosition() - pos; + float dist = camDir.Magnitude(); + camDir *= 2.0f/dist; + glareDir += camDir; + glareDir.Normalise(); + float camAngle = -DotProduct(glareDir, CTimeCycle::GetSunDirection()); + if(camAngle > 0.0f){ + float intens = Sqrt(camAngle) * CWeather::SunGlare; + pos += camDir; + CCoronas::RegisterCorona((uintptr)this + 33 + i, + intens * (CTimeCycle::GetSunCoreRed() + 2*255)/3.0f, + intens * (CTimeCycle::GetSunCoreGreen() + 2*255)/3.0f, + intens * (CTimeCycle::GetSunCoreBlue() + 2*255)/3.0f, + 255, + pos, 0.5f*CWeather::SunGlare*Sqrt(dist), 120.0f, + CCoronas::TYPE_STAR, CCoronas::FLARE_NONE, + CCoronas::REFLECTION_OFF, CCoronas::LOSCHECK_OFF, + CCoronas::STREAK_OFF, 0.0f); + } } + break; } } } @@ -849,27 +948,31 @@ CEntity::ModifyMatrixForTreeInWind(void) CMatrix mat(GetMatrix().m_attachment); if(CWeather::Wind >= 0.5){ - t = m_randomSeed + 16*CTimer::GetTimeInMilliseconds(); + t = m_randomSeed + 8*CTimer::GetTimeInMilliseconds(); f = (t & 0xFFF)/(float)0x1000; flutter = f * WindTabel[(t>>12)+1 & 0xF] + (1.0f - f) * WindTabel[(t>>12) & 0xF] + 1.0f; - strength = CWeather::Wind < 0.8f ? 0.008f : 0.014f; + strength = -0.015f*CWeather::Wind; }else if(CWeather::Wind >= 0.2){ t = (uintptr)this + CTimer::GetTimeInMilliseconds(); f = (t & 0xFFF)/(float)0x1000; flutter = Sin(f * 6.28f); - strength = 0.008f; + strength = -0.008f; }else{ t = (uintptr)this + CTimer::GetTimeInMilliseconds(); f = (t & 0xFFF)/(float)0x1000; flutter = Sin(f * 6.28f); - strength = 0.005f; + strength = -0.005f; } mat.GetUp().x = strength * flutter; + if(IsPalmTreeModel(GetModelIndex())) + mat.GetUp().x += -0.07f*CWeather::Wind; mat.GetUp().y = mat.GetUp().x; + CWindModifiers::FindWindModifier(GetPosition(), &mat.GetUp().x, &mat.GetUp().y); + mat.UpdateRW(); UpdateRwFrame(); } @@ -881,6 +984,7 @@ float BannerWindTabel[] = { 0.28f, 0.28f, 0.22f, 0.1f, 0.0f, -0.1f, -0.17f, -0.12f }; +//--MIAMI: unused void CEntity::ModifyMatrixForBannerInWind(void) { @@ -928,7 +1032,6 @@ CEntity::AddSteamsFromGround(CPtrList& list) } #ifdef COMPATIBLE_SAVES -// TODO(MIAMI) void CEntity::SaveEntityFlags(uint8*& buf) { @@ -952,35 +1055,41 @@ CEntity::SaveEntityFlags(uint8*& buf) if (bRenderScorched) tmp |= BIT(20); if (bHasBlip) tmp |= BIT(21); if (bIsBIGBuilding) tmp |= BIT(22); - if (bRenderDamaged) tmp |= BIT(23); + if (bStreamBIGBuilding) tmp |= BIT(23); - if (bBulletProof) tmp |= BIT(24); - if (bFireProof) tmp |= BIT(25); - if (bCollisionProof) tmp |= BIT(26); - if (bMeleeProof) tmp |= BIT(27); - if (bOnlyDamagedByPlayer) tmp |= BIT(28); - if (bStreamingDontDelete) tmp |= BIT(29); - if (bRemoveFromWorld) tmp |= BIT(0); - if (bHasHitWall) tmp |= BIT(1); + if (bRenderDamaged) tmp |= BIT(24); + if (bBulletProof) tmp |= BIT(25); + if (bFireProof) tmp |= BIT(26); + if (bCollisionProof) tmp |= BIT(27); + if (bMeleeProof) tmp |= BIT(28); + if (bOnlyDamagedByPlayer) tmp |= BIT(29); + if (bStreamingDontDelete) tmp |= BIT(30); + if (bRemoveFromWorld) tmp |= BIT(31); WriteSaveBuf(buf, tmp); tmp = 0; - if (bImBeingRendered) tmp |= BIT(2); - if (bTouchingWater) tmp |= BIT(3); - if (bIsSubway) tmp |= BIT(4); - if (bDrawLast) tmp |= BIT(5); - if (bNoBrightHeadLights) tmp |= BIT(6); - if (bDoNotRender) tmp |= BIT(7); - if (bDistanceFade) tmp |= BIT(8); + if (bHasHitWall) tmp |= BIT(0); + if (bImBeingRendered) tmp |= BIT(1); + if (bTouchingWater) tmp |= BIT(2); + if (bIsSubway) tmp |= BIT(3); + if (bDrawLast) tmp |= BIT(4); + if (bNoBrightHeadLights) tmp |= BIT(5); + if (bDoNotRender) tmp |= BIT(6); + if (bDistanceFade) tmp |= BIT(7); + if (m_flagE1) tmp |= BIT(8); if (m_flagE2) tmp |= BIT(9); + if (bOffscreen) tmp |= BIT(10); + if (bIsStaticWaitingForCollision) tmp |= BIT(11); + if (m_flagE10) tmp |= BIT(12); + if (bUnderwater) tmp |= BIT(13); + if (bHasPreRenderEffects) tmp |= BIT(14); WriteSaveBuf(buf, tmp); } -// TODO(MIAMI) void CEntity::LoadEntityFlags(uint8*& buf) { @@ -1004,28 +1113,50 @@ CEntity::LoadEntityFlags(uint8*& buf) bRenderScorched = !!(tmp & BIT(20)); bHasBlip = !!(tmp & BIT(21)); bIsBIGBuilding = !!(tmp & BIT(22)); - bRenderDamaged = !!(tmp & BIT(23)); + bStreamBIGBuilding = !!(tmp & BIT(23)); - bBulletProof = !!(tmp & BIT(24)); - bFireProof = !!(tmp & BIT(25)); - bCollisionProof = !!(tmp & BIT(26)); - bMeleeProof = !!(tmp & BIT(27)); - bOnlyDamagedByPlayer = !!(tmp & BIT(28)); - bStreamingDontDelete = !!(tmp & BIT(29)); - bRemoveFromWorld = !!(tmp & BIT(0)); - bHasHitWall = !!(tmp & BIT(1)); + bRenderDamaged = !!(tmp & BIT(24)); + bBulletProof = !!(tmp & BIT(25)); + bFireProof = !!(tmp & BIT(26)); + bCollisionProof = !!(tmp & BIT(27)); + bMeleeProof = !!(tmp & BIT(28)); + bOnlyDamagedByPlayer = !!(tmp & BIT(29)); + bStreamingDontDelete = !!(tmp & BIT(30)); + bRemoveFromWorld = !!(tmp & BIT(31)); tmp = ReadSaveBuf(buf); - bImBeingRendered = !!(tmp & BIT(2)); - bTouchingWater = !!(tmp & BIT(3)); - bIsSubway = !!(tmp & BIT(4)); - bDrawLast = !!(tmp & BIT(5)); - bNoBrightHeadLights = !!(tmp & BIT(6)); - bDoNotRender = !!(tmp & BIT(7)); - bDistanceFade = !!(tmp & BIT(8)); + bHasHitWall = !!(tmp & BIT(0)); + bImBeingRendered = !!(tmp & BIT(1)); + bTouchingWater = !!(tmp & BIT(2)); + bIsSubway = !!(tmp & BIT(3)); + bDrawLast = !!(tmp & BIT(4)); + bNoBrightHeadLights = !!(tmp & BIT(5)); + bDoNotRender = !!(tmp & BIT(6)); + bDistanceFade = !!(tmp & BIT(7)); + m_flagE1 = !!(tmp & BIT(8)); m_flagE2 = !!(tmp & BIT(9)); + bOffscreen = !!(tmp & BIT(10)); + bIsStaticWaitingForCollision = !!(tmp & BIT(11)); + m_flagE10 = !!(tmp & BIT(12)); + bUnderwater = !!(tmp & BIT(13)); + bHasPreRenderEffects = !!(tmp & BIT(14)); } #endif + +bool IsEntityPointerValid(CEntity* pEntity) +{ + if (!pEntity) + return false; + switch (pEntity->GetType()) { + case ENTITY_TYPE_NOTHING: return false; + case ENTITY_TYPE_BUILDING: return IsBuildingPointerValid((CBuilding*)pEntity); + case ENTITY_TYPE_VEHICLE: return IsVehiclePointerValid((CVehicle*)pEntity); + case ENTITY_TYPE_PED: return IsPedPointerValid((CPed*)pEntity); + case ENTITY_TYPE_OBJECT: return IsObjectPointerValid((CObject*)pEntity); + case ENTITY_TYPE_DUMMY: return IsDummyPointerValid((CDummy*)pEntity); + } + return false; +} diff --git a/src/entities/Entity.h b/src/entities/Entity.h index fa57519e..e7d402d0 100644 --- a/src/entities/Entity.h +++ b/src/entities/Entity.h @@ -30,6 +30,7 @@ enum eEntityStatus : uint8 STATUS_PLANE, STATUS_PLAYER_REMOTE, STATUS_PLAYER_DISABLED, + STATUS_12, // TODO: what is this? used in CPhysical::ApplyAirResistance }; class CEntity : public CPlaceable @@ -78,7 +79,7 @@ public: uint32 bIsSubway : 1; // set when subway, but maybe different meaning? uint32 bDrawLast : 1; // draw object last uint32 bNoBrightHeadLights : 1; - uint32 bDoNotRender : 1; + uint32 bDoNotRender : 1; //-- only applies to CObjects apparently uint32 bDistanceFade : 1; // Fade entity because it is far away // flagsE @@ -88,7 +89,7 @@ public: uint32 bIsStaticWaitingForCollision : 1; // this is used by script created entities - they are static until the collision is loaded below them uint32 m_flagE10 : 1; // probably bDontStream uint32 bUnderwater : 1; // this object is underwater change drawing order - uint32 m_flagE40 : 1; + uint32 bHasPreRenderEffects : 1; // Object has a prerender effects attached to it uint16 m_scanCode; uint16 m_randomSeed; @@ -112,12 +113,12 @@ public: #endif CEntity(void); - ~CEntity(void); + virtual ~CEntity(void); virtual void Add(void); virtual void Remove(void); - virtual void SetModelIndex(uint32 id) { m_modelIndex = id; CreateRwObject(); } - virtual void SetModelIndexNoCreate(uint32 id) { m_modelIndex = id; } + virtual void SetModelIndex(uint32 id); + virtual void SetModelIndexNoCreate(uint32 id); virtual void CreateRwObject(void); virtual void DeleteRwObject(void); virtual CRect GetBoundRect(void); @@ -160,6 +161,7 @@ public: int16 GetModelIndex(void) const { return m_modelIndex; } void UpdateRwFrame(void); void SetupBigBuilding(void); + bool HasPreRenderEffects(void); void AttachToRwObject(RwObject *obj); void DetachFromRwObject(void); @@ -180,3 +182,5 @@ public: static void AddSteamsFromGround(CPtrList& list); }; + +bool IsEntityPointerValid(CEntity*); diff --git a/src/entities/Physical.cpp b/src/entities/Physical.cpp index 22b391e8..02feb5cb 100644 --- a/src/entities/Physical.cpp +++ b/src/entities/Physical.cpp @@ -1,7 +1,9 @@ #include "common.h" #include "World.h" +#include "General.h" #include "Timer.h" +#include "Stats.h" #include "ModelIndices.h" #include "Treadable.h" #include "Vehicle.h" @@ -15,8 +17,11 @@ #include "CarCtrl.h" #include "DMAudio.h" #include "Automobile.h" +#include "Pickups.h" #include "Physical.h" +//--MIAMI: file done except one bike thing + CPhysical::CPhysical(void) { int i; @@ -37,6 +42,7 @@ CPhysical::CPhysical(void) m_aCollisionRecords[i] = nil; m_bIsVehicleBeingShifted = false; + bJustCheckCollision = false; m_nDamagePieceType = 0; m_fDamageImpulse = 0.0f; @@ -45,25 +51,26 @@ CPhysical::CPhysical(void) bUsesCollision = true; m_audioEntityId = -5; - unk1 = 100.0f; + m_phys_unused1 = 100.0f; m_vecCentreOfMass = CVector(0.0f, 0.0f, 0.0f); - field_EC = 0; + m_phys_unused2 = 0; bIsHeavy = false; bAffectedByGravity = true; bInfiniteMass = false; + m_phy_flagA08 = false; bIsInWater = false; bHitByTrain = false; bSkipLineCol = false; m_fDistanceTravelled = 0.0f; - m_treadable[PATH_CAR] = nil; - m_treadable[PATH_PED] = nil; - m_phy_flagA10 = false; m_phy_flagA20 = false; m_nZoneLevel = LEVEL_NONE; + + bIsFrozen = false; + bDontLoadCollision = false; } CPhysical::~CPhysical(void) @@ -264,7 +271,6 @@ CPhysical::AddCollisionRecord(CEntity *ent) } } -//--MIAMI: done void CPhysical::AddCollisionRecord_Treadable(CEntity *ent) { @@ -401,18 +407,26 @@ CPhysical::GetSpeed(const CVector &r) void CPhysical::ApplyMoveSpeed(void) { - GetMatrix().Translate(m_vecMoveSpeed * CTimer::GetTimeStep()); + if(bIsFrozen) + m_vecMoveSpeed = CVector(0.0f, 0.0f, 0.0f); + else + GetMatrix().Translate(m_vecMoveSpeed * CTimer::GetTimeStep()); } + void CPhysical::ApplyTurnSpeed(void) { - // Move the coordinate axes by their speed - // Note that this denormalizes the matrix - CVector turnvec = m_vecTurnSpeed*CTimer::GetTimeStep(); - GetRight() += CrossProduct(turnvec, GetRight()); - GetForward() += CrossProduct(turnvec, GetForward()); - GetUp() += CrossProduct(turnvec, GetUp()); + if(bIsFrozen){ + m_vecTurnSpeed = CVector(0.0f, 0.0f, 0.0f); + }else{ + // Move the coordinate axes by their speed + // Note that this denormalizes the matrix + CVector turnvec = m_vecTurnSpeed*CTimer::GetTimeStep(); + GetRight() += CrossProduct(turnvec, GetRight()); + GetForward() += CrossProduct(turnvec, GetForward()); + GetUp() += CrossProduct(turnvec, GetUp()); + } } void @@ -456,6 +470,21 @@ CPhysical::ApplySpringCollision(float springConst, CVector &springDir, CVector & return true; } +bool +CPhysical::ApplySpringCollisionAlt(float springConst, CVector &springDir, CVector &point, float springRatio, float bias, CVector &forceDir) +{ + float compression = 1.0f - springRatio; + if(compression > 0.0f){ + if(DotProduct(springDir, forceDir) > 0.0f) + forceDir *= -1.0f; + float step = Min(CTimer::GetTimeStep(), 3.0f); + float impulse = -GRAVITY*m_fMass*step * springConst * compression * bias*2.0f; + ApplyMoveForce(forceDir*impulse); + ApplyTurnForce(forceDir*impulse, point); + } + return true; +} + // What exactly is speed? bool CPhysical::ApplySpringDampening(float damping, CVector &springDir, CVector &point, CVector &speed) @@ -464,6 +493,8 @@ CPhysical::ApplySpringDampening(float damping, CVector &springDir, CVector &poin float speedB = DotProduct(GetSpeed(point), springDir); float step = Min(CTimer::GetTimeStep(), 3.0f); float impulse = -damping * (speedA + speedB)/2.0f * m_fMass * step * 0.53f; + if(bIsHeavy) + impulse *= 2.0f; // what is this? float a = m_fTurnMass / ((point.MagnitudeSqr() + 1.0f) * 2.0f * m_fMass); @@ -497,9 +528,11 @@ void CPhysical::ApplyAirResistance(void) { if(m_fAirResistance > 0.1f){ - float f = Pow(m_fAirResistance, CTimer::GetTimeStep()); - m_vecMoveSpeed *= f; - m_vecTurnSpeed *= f; + if(GetStatus() != STATUS_12){ + float f = Pow(m_fAirResistance, CTimer::GetTimeStep()); + m_vecMoveSpeed *= f; + m_vecTurnSpeed *= f; + } }else{ float f = Pow(1.0f/(m_fAirResistance*0.5f*m_vecMoveSpeed.MagnitudeSqr() + 1.0f), CTimer::GetTimeStep()); m_vecMoveSpeed *= f; @@ -507,7 +540,6 @@ CPhysical::ApplyAirResistance(void) } } - bool CPhysical::ApplyCollision(CPhysical *B, CColPoint &colpoint, float &impulseA, float &impulseB) { @@ -515,32 +547,38 @@ CPhysical::ApplyCollision(CPhysical *B, CColPoint &colpoint, float &impulseA, fl CPhysical *A = this; CObject *Bobj = (CObject*)B; + bool foo = false; // TODO: what does this mean? bool ispedcontactA = false; bool ispedcontactB = false; - float timestepA; + float massFactorA; if(B->bPedPhysics){ - timestepA = 10.0f; + massFactorA = 10.0f; if(B->IsPed() && ((CPed*)B)->m_pCurrentPhysSurface == A) ispedcontactA = true; }else - timestepA = A->bIsHeavy ? 2.0f : 1.0f; + massFactorA = A->bIsHeavy ? 2.0f : 1.0f; - float timestepB; + float massFactorB; if(A->bPedPhysics){ if(A->IsPed() && ((CPed*)A)->IsPlayer() && B->IsVehicle() && (B->GetStatus() == STATUS_ABANDONED || B->GetStatus() == STATUS_WRECKED || A->bHasHitWall)) - timestepB = 2200.0f / B->m_fMass; + massFactorB = 1.0f/(Max(B->m_fMass - 2000.0f, 0.0f)/5000.0f + 1.0f); else - timestepB = 10.0f; + massFactorB = 10.0f; if(A->IsPed() && ((CPed*)A)->m_pCurrentPhysSurface == B) ispedcontactB = true; }else - timestepB = B->bIsHeavy ? 2.0f : 1.0f; + massFactorB = B->bIsHeavy ? 2.0f : 1.0f; + + if(B->bInfiniteMass && !B->m_phy_flagA08){ + ispedcontactB = false; + foo = true; + } float speedA, speedB; - if(B->IsStatic()){ + if(B->IsStatic() && !foo){ if(A->bPedPhysics){ speedA = DotProduct(A->m_vecMoveSpeed, colpoint.normal); if(speedA < 0.0f){ @@ -550,8 +588,11 @@ CPhysical::ApplyCollision(CPhysical *B, CColPoint &colpoint, float &impulseA, fl if(impulseA > Bobj->m_fUprootLimit){ if(IsGlass(B->GetModelIndex())) CGlass::WindowRespondsToCollision(B, impulseA, A->m_vecMoveSpeed, colpoint.point, false); - else if(!B->bInfiniteMass) + else if(!B->bInfiniteMass){ B->bIsStatic = false; + CWorld::Players[CWorld::PlayerInFocus].m_nHavocLevel += 2; + CStats::PropertyDestroyed += CGeneral::GetRandomNumberInRange(30, 60); + } }else{ if(IsGlass(B->GetModelIndex())) CGlass::WindowRespondsToSoftCollision(B, impulseA); @@ -603,6 +644,9 @@ CPhysical::ApplyCollision(CPhysical *B, CColPoint &colpoint, float &impulseA, fl if(model == MI_FIRE_HYDRANT && !Bobj->bHasBeenDamaged){ CParticleObject::AddObject(POBJECT_FIRE_HYDRANT, B->GetPosition() - CVector(0.0f, 0.0f, 0.5f), true); Bobj->bHasBeenDamaged = true; + }else if(model == MI_PARKINGMETER || model == MI_PARKINGMETER2){ + CPickups::CreateSomeMoney(GetPosition(), CGeneral::GetRandomNumber()%100); + Bobj->bHasBeenDamaged = true; }else if(B->IsObject() && !IsExplosiveThingModel(model)) Bobj->bHasBeenDamaged = true; }else{ @@ -625,7 +669,7 @@ CPhysical::ApplyCollision(CPhysical *B, CColPoint &colpoint, float &impulseA, fl if(B->IsStatic()) return false; - if(!B->bInfiniteMass) + if(!B->bInfiniteMass && !B->m_phy_flagA08) B->AddToMovingList(); } @@ -635,16 +679,36 @@ CPhysical::ApplyCollision(CPhysical *B, CColPoint &colpoint, float &impulseA, fl // negative if A is moving towards B speedA = DotProduct(A->m_vecMoveSpeed, colpoint.normal); // positive if B is moving towards A - // not interested in how much B moves into A apparently? - // only interested in cases where A collided into B - speedB = Max(0.0f, DotProduct(B->m_vecMoveSpeed, colpoint.normal)); - // A has moved into B - if(speedA < speedB){ - if(!A->bHasHitWall) - speedB -= (speedA - speedB) * (A->m_fElasticity+B->m_fElasticity)/2.0f; - impulseA = (speedB-speedA) * A->m_fMass * timestepA; + float speedB = DotProduct(B->m_vecMoveSpeed, colpoint.normal); + + bool affectB = false; + float mA = A->m_fMass;; + float mB = B->m_fMass;; + float speedSum; + if(((CPed*)A)->GetPedState() == PED_FOLLOW_PATH){ + affectB = true; + speedSum = (2.0f*mA*speedA + mB*speedB)/(2.0f*mA + mB); + }else{ + speedSum = Max(speedB, 0.0f); + } + + if(speedA < speedSum){ + if(A->bHasHitWall) + eA = speedSum; + else + eA = speedSum - (speedA - speedSum) * (A->m_fElasticity+B->m_fElasticity)/2.0f; + impulseA = (eA-speedA) * mA; if(!A->bInfiniteMass) - A->ApplyMoveForce(colpoint.normal*(impulseA/timestepA)); + A->ApplyMoveForce(colpoint.normal*impulseA); + if(affectB && speedB < speedSum){ + if(B->bHasHitWall) + eB = speedSum; + else + eB = speedSum - (speedB - speedSum) * (A->m_fElasticity+B->m_fElasticity)/2.0f; + impulseB = -(eB-speedB) * mB; + if(!B->bInfiniteMass) + B->ApplyMoveForce(colpoint.normal*-impulseB); + } return true; } }else if(A->bPedPhysics){ @@ -652,9 +716,13 @@ CPhysical::ApplyCollision(CPhysical *B, CColPoint &colpoint, float &impulseA, fl speedA = DotProduct(A->m_vecMoveSpeed, colpoint.normal); speedB = DotProduct(B->GetSpeed(pointposB), colpoint.normal); - float a = A->m_fMass*timestepA; - float b = B->GetMassTime(pointposB, colpoint.normal, timestepB); - float speedSum = (b*speedB + a*speedA)/(a + b); + float mA = A->m_fMass*massFactorA; + float mB = B->GetMassTweak(pointposB, colpoint.normal, massFactorB); + float speedSum; + if(foo) + speedSum = speedB; + else + speedSum = (mB*speedB + mA*speedA)/(mA + mB); if(speedA < speedSum){ if(A->bHasHitWall) eA = speedSum; @@ -664,10 +732,10 @@ CPhysical::ApplyCollision(CPhysical *B, CColPoint &colpoint, float &impulseA, fl eB = speedSum; else eB = speedSum - (speedB - speedSum) * (A->m_fElasticity+B->m_fElasticity)/2.0f; - impulseA = (eA - speedA) * a; - impulseB = -(eB - speedB) * b; - CVector fA = colpoint.normal*(impulseA/timestepA); - CVector fB = colpoint.normal*(-impulseB/timestepB); + impulseA = (eA - speedA) * mA; + impulseB = -(eB - speedB) * mB; + CVector fA = colpoint.normal*(impulseA/massFactorA); + CVector fB = colpoint.normal*(-impulseB/massFactorB); if(!A->bInfiniteMass){ if(fA.z < 0.0f) fA.z = 0.0f; if(ispedcontactB){ @@ -687,9 +755,9 @@ CPhysical::ApplyCollision(CPhysical *B, CColPoint &colpoint, float &impulseA, fl speedA = DotProduct(A->GetSpeed(pointposA), colpoint.normal); speedB = DotProduct(B->m_vecMoveSpeed, colpoint.normal); - float a = A->GetMassTime(pointposA, colpoint.normal, timestepA); - float b = B->m_fMass*timestepB; - float speedSum = (b*speedB + a*speedA)/(a + b); + float mA = A->GetMassTweak(pointposA, colpoint.normal, massFactorA); + float mB = B->m_fMass*massFactorB; + float speedSum = (mB*speedB + mA*speedA)/(mA + mB); if(speedA < speedSum){ if(A->bHasHitWall) eA = speedSum; @@ -699,10 +767,10 @@ CPhysical::ApplyCollision(CPhysical *B, CColPoint &colpoint, float &impulseA, fl eB = speedSum; else eB = speedSum - (speedB - speedSum) * (A->m_fElasticity+B->m_fElasticity)/2.0f; - impulseA = (eA - speedA) * a; - impulseB = -(eB - speedB) * b; - CVector fA = colpoint.normal*(impulseA/timestepA); - CVector fB = colpoint.normal*(-impulseB/timestepB); + impulseA = (eA - speedA) * mA; + impulseB = -(eB - speedB) * mB; + CVector fA = colpoint.normal*(impulseA/massFactorA); + CVector fB = colpoint.normal*(-impulseB/massFactorB); if(!A->bInfiniteMass && !ispedcontactA){ if(fA.z < 0.0f) fA.z = 0.0f; A->ApplyMoveForce(fA); @@ -727,9 +795,9 @@ CPhysical::ApplyCollision(CPhysical *B, CColPoint &colpoint, float &impulseA, fl CVector pointposB = colpoint.point - B->GetPosition(); speedA = DotProduct(A->GetSpeed(pointposA), colpoint.normal); speedB = DotProduct(B->GetSpeed(pointposB), colpoint.normal); - float a = A->GetMassTime(pointposA, colpoint.normal, timestepA); - float b = B->GetMassTime(pointposB, colpoint.normal, timestepB); - float speedSum = (b*speedB + a*speedA)/(a + b); + float mA = A->GetMassTweak(pointposA, colpoint.normal, massFactorA); + float mB = B->GetMassTweak(pointposB, colpoint.normal, massFactorB); + float speedSum = (mB*speedB + mA*speedA)/(mA + mB); if(speedA < speedSum){ if(A->bHasHitWall) eA = speedSum; @@ -739,10 +807,10 @@ CPhysical::ApplyCollision(CPhysical *B, CColPoint &colpoint, float &impulseA, fl eB = speedSum; else eB = speedSum - (speedB - speedSum) * (A->m_fElasticity+B->m_fElasticity)/2.0f; - impulseA = (eA - speedA) * a; - impulseB = -(eB - speedB) * b; - CVector fA = colpoint.normal*(impulseA/timestepA); - CVector fB = colpoint.normal*(-impulseB/timestepB); + impulseA = (eA - speedA) * mA; + impulseB = -(eB - speedB) * mB; + CVector fA = colpoint.normal*(impulseA/massFactorA); + CVector fB = colpoint.normal*(-impulseB/massFactorB); if(A->IsVehicle() && !A->bHasHitWall){ fA.x *= 1.4f; fA.y *= 1.4f; @@ -758,7 +826,7 @@ CPhysical::ApplyCollision(CPhysical *B, CColPoint &colpoint, float &impulseA, fl if(B->IsVehicle() && !B->bHasHitWall){ fB.x *= 1.4f; fB.y *= 1.4f; - if(colpoint.normal.z < 0.7f) + if(-colpoint.normal.z < 0.7f) fB.z *= 0.3f; if(B->GetStatus() == STATUS_PLAYER) pointposB *= 0.8f; @@ -784,14 +852,53 @@ CPhysical::ApplyCollision(CPhysical *B, CColPoint &colpoint, float &impulseA, fl return false; } +bool +CPhysical::ApplyCollision(CColPoint &colpoint, float &impulse) +{ + float speed; + if(bPedPhysics){ + speed = DotProduct(m_vecMoveSpeed, colpoint.normal); + if(speed < 0.0f){ + impulse = -speed * m_fMass; + ApplyMoveForce(colpoint.normal*impulse); + return true; + } + }else{ + CVector pointpos = colpoint.point - GetPosition(); + speed = DotProduct(GetSpeed(pointpos), colpoint.normal); + + if(speed < 0.0f){ + float mass = GetMass(pointpos, colpoint.normal); + impulse = -(m_fElasticity + 1.0f) * speed * mass; + CVector f = colpoint.normal*impulse; + if(IsVehicle()){ + f.x *= 1.4f; + f.y *= 1.4f; + if(colpoint.normal.z < 0.7f) + f.z *= 0.3f; + } + if(!bInfiniteMass){ + ApplyMoveForce(f); + if(!IsVehicle() || !CWorld::bNoMoreCollisionTorque) + ApplyTurnForce(f, pointpos); + } + return true; + } + } + + return false; +} + bool CPhysical::ApplyCollisionAlt(CEntity *B, CColPoint &colpoint, float &impulse, CVector &moveSpeed, CVector &turnSpeed) { float normalSpeed; - float e; CVector speed; CVector vImpulse; + if(GetModelIndex() == MI_BEACHBALL && B != (CEntity*)FindPlayerPed()) + ((CObject*)this)->m_nBeachballBounces = 0; + if(bPedPhysics){ normalSpeed = DotProduct(m_vecMoveSpeed, colpoint.normal); if(normalSpeed < 0.0f){ @@ -804,28 +911,61 @@ CPhysical::ApplyCollisionAlt(CEntity *B, CColPoint &colpoint, float &impulse, CV speed = GetSpeed(pointpos); normalSpeed = DotProduct(speed, colpoint.normal); if(normalSpeed < 0.0f){ - float minspeed = 0.0104f * CTimer::GetTimeStep(); -#ifdef GTA3_1_1_PATCH - if ((IsObject() || IsVehicle() && (GetUp().z < -0.3f || ((CVehicle*)this)->IsBike() && (GetStatus() == STATUS_ABANDONED || GetStatus() == STATUS_WRECKED))) && -#else - if((IsObject() || IsVehicle() && GetUp().z < -0.3f) && -#endif - !bHasContacted && + int16 elasticityType = 0; + float mass = GetMass(pointpos, colpoint.normal); + float minspeed = GRAVITY * CTimer::GetTimeStep(); + + if(IsObject()) + elasticityType = 1; + else if(IsVehicle() && !bIsInWater){ + if(((CVehicle*)this)->IsBike() && (GetStatus() == STATUS_ABANDONED || GetStatus() == STATUS_WRECKED)){ + minspeed *= 1.3f; + elasticityType = 3; + }else if(((CVehicle*)this)->IsBoat()){ + minspeed *= 1.2f; + elasticityType = 4; + }else if(GetUp().z < -0.3f){ + minspeed *= 1.1f; + elasticityType = 2; + } + } + + if(elasticityType == 1 && !bHasContacted && Abs(m_vecMoveSpeed.x) < minspeed && Abs(m_vecMoveSpeed.y) < minspeed && Abs(m_vecMoveSpeed.z) < minspeed*2.0f) - e = -1.0f; + impulse = -0.98f * normalSpeed * mass; + if(elasticityType == 3 && + Abs(m_vecMoveSpeed.x) < minspeed && + Abs(m_vecMoveSpeed.y) < minspeed && + Abs(m_vecMoveSpeed.z) < minspeed*2.0f) + impulse = -0.8f * normalSpeed * mass; + else if(elasticityType == 2 && + Abs(m_vecMoveSpeed.x) < minspeed && + Abs(m_vecMoveSpeed.y) < minspeed && + Abs(m_vecMoveSpeed.z) < minspeed*2.0f) + impulse = -0.92f * normalSpeed * mass; + else if(elasticityType == 4 && + Abs(m_vecMoveSpeed.x) < minspeed && + Abs(m_vecMoveSpeed.y) < minspeed && + Abs(m_vecMoveSpeed.z) < minspeed*2.0f) + impulse = -0.8f * normalSpeed * mass; + else if(IsVehicle() && ((CVehicle*)this)->IsBoat() && + colpoint.surfaceB == SURFACE_WOOD_SOLID && colpoint.normal.z < 0.5f) + impulse = -(2.0f * m_fElasticity + 1.0f) * normalSpeed * mass; else - e = -(m_fElasticity + 1.0f); - impulse = normalSpeed * e * GetMass(pointpos, colpoint.normal); + impulse = -(m_fElasticity + 1.0f) * normalSpeed * mass; // ApplyMoveForce vImpulse = colpoint.normal*impulse; - if(IsVehicle() && - (!bHasHitWall || - !(m_vecMoveSpeed.MagnitudeSqr() > 0.1 || !(B->IsBuilding() || ((CPhysical*)B)->bInfiniteMass)))) - moveSpeed += vImpulse * 1.2f * (1.0f/m_fMass); - else + if(IsVehicle()){ + if(!bHasHitWall || + !(m_vecMoveSpeed.MagnitudeSqr() > 0.1 || !(B->IsBuilding() || ((CPhysical*)B)->bInfiniteMass))) + moveSpeed += vImpulse * 1.2f * (1.0f/m_fMass); + else + moveSpeed += vImpulse * (1.0f/m_fMass); + vImpulse *= 0.8f; + }else moveSpeed += vImpulse * (1.0f/m_fMass); // ApplyTurnForce @@ -1006,7 +1146,7 @@ CPhysical::ApplyFriction(float adhesiveLimit, CColPoint &colpoint) ApplyFrictionTurnForce(frictionDir*fImpulse, pointpos); if(fOtherSpeed > 0.1f && - colpoint.surfaceB != SURFACE_2 && colpoint.surfaceB != SURFACE_4 && + colpoint.surfaceB != SURFACE_GRASS && colpoint.surfaceB != SURFACE_MUD_DRY && CSurfaceTable::GetAdhesionGroup(colpoint.surfaceA) == ADHESIVE_HARD){ CVector v = frictionDir * fOtherSpeed * 0.25f; for(int i = 0; i < 4; i++) @@ -1055,7 +1195,7 @@ CPhysical::ProcessShiftSectorList(CPtrList *lists) canshift = true; else canshift = A->IsPed() && - B->IsObject() && B->bInfiniteMass && !Bobj->bHasBeenDamaged; + B->IsObject() && B->IsStatic() && !Bobj->bHasBeenDamaged; if(B == A || B->m_scanCode == CWorld::GetCurrentScanCode() || !B->bUsesCollision || @@ -1067,15 +1207,14 @@ CPhysical::ProcessShiftSectorList(CPtrList *lists) if(B->IsBuilding()) skipShift = false; - else if(IsTrafficLight(A->GetModelIndex()) && + else if(IsLightWithoutShift(A->GetModelIndex()) && (B->IsVehicle() || B->IsPed()) && A->GetUp().z < 0.66f) skipShift = true; else if((A->IsVehicle() || A->IsPed()) && B->GetUp().z < 0.66f && - IsTrafficLight(B->GetModelIndex())) + IsLightWithoutShift(B->GetModelIndex())) skipShift = true; -// TODO: maybe flip some ifs here else if(A->IsObject() && B->IsVehicle()){ CObject *Aobj = (CObject*)A; if(Aobj->ObjectCreatedBy != TEMP_OBJECT && @@ -1194,6 +1333,9 @@ CPhysical::ProcessCollisionSectorList_SimpleCar(CPtrList *lists) A = (CPhysical*)this; + if(!A->bUsesCollision) + return false; + radius = A->GetBoundRadius(); A->GetBoundCentre(center); @@ -1212,6 +1354,7 @@ CPhysical::ProcessCollisionSectorList_SimpleCar(CPtrList *lists) for(listnode = list->first; listnode; listnode = listnode->next){ B = (CPhysical*)listnode->item; if(B != A && + !(B->IsObject() && ((CObject*)B)->bIsStreetLight && B->GetUp().z < 0.66f) && B->m_scanCode != CWorld::GetCurrentScanCode() && B->bUsesCollision && B->GetIsTouching(center, radius)){ @@ -1355,6 +1498,7 @@ CPhysical::ProcessCollisionSectorList(CPtrList *lists) int numResponses; int i, j; bool skipCollision, altcollision; + bool ret = false; float impulseA = -1.0f; float impulseB = -1.0f; @@ -1375,9 +1519,9 @@ CPhysical::ProcessCollisionSectorList(CPtrList *lists) Bped = (CPed*)B; bool isTouching = true; - if(B == A || + if(!B->bUsesCollision || B->m_scanCode == CWorld::GetCurrentScanCode() || - !B->bUsesCollision || + B == A || !(isTouching = B->GetIsTouching(center, radius))){ if(!isTouching){ if(A->IsObject() && Aobj->m_pCollidingEntity == B) @@ -1398,27 +1542,27 @@ CPhysical::ProcessCollisionSectorList(CPtrList *lists) if(B->IsBuilding()) skipCollision = false; - else if(IsTrafficLight(A->GetModelIndex()) && + else if(A->IsObject() && Aobj->bIsStreetLight && (B->IsVehicle() || B->IsPed()) && A->GetUp().z < 0.66f){ skipCollision = true; A->bSkipLineCol = true; Aobj->m_pCollidingEntity = B; - }else if((A->IsVehicle() || A->IsPed()) && - B->GetUp().z < 0.66f && - IsTrafficLight(B->GetModelIndex())){ + }else if(B->IsObject() && Bobj->bIsStreetLight && + (A->IsVehicle() || A->IsPed()) && + B->GetUp().z < 0.66f){ skipCollision = true; A->bSkipLineCol = true; Bobj->m_pCollidingEntity = A; }else if(A->IsObject() && B->IsVehicle()){ - if(A->GetModelIndex() == MI_CAR_BUMPER || A->GetModelIndex() == MI_FILES) + if(A->GetModelIndex() == MI_CAR_BUMPER) skipCollision = true; else if(Aobj->ObjectCreatedBy == TEMP_OBJECT || Aobj->bHasBeenDamaged || !Aobj->IsStatic()){ if(Aobj->m_pCollidingEntity == B) skipCollision = true; - else{ + else if(Aobj->m_nCollisionDamageEffect < DAMAGE_EFFECT_SMASH_COMPLETELY){ CMatrix inv; CVector size = CModelInfo::GetModelInfo(A->GetModelIndex())->GetColModel()->boundingBox.GetSize(); size = A->GetMatrix() * size; @@ -1430,14 +1574,14 @@ CPhysical::ProcessCollisionSectorList(CPtrList *lists) } } }else if(B->IsObject() && A->IsVehicle()){ - if(B->GetModelIndex() == MI_CAR_BUMPER || B->GetModelIndex() == MI_FILES) + if(B->GetModelIndex() == MI_CAR_BUMPER) skipCollision = true; else if(Bobj->ObjectCreatedBy == TEMP_OBJECT || Bobj->bHasBeenDamaged || !Bobj->IsStatic()){ if(Bobj->m_pCollidingEntity == A) skipCollision = true; - else{ + else if(Bobj->m_nCollisionDamageEffect < DAMAGE_EFFECT_SMASH_COMPLETELY){ CMatrix inv; CVector size = CModelInfo::GetModelInfo(B->GetModelIndex())->GetColModel()->boundingBox.GetSize(); size = B->GetMatrix() * size; @@ -1447,14 +1591,16 @@ CPhysical::ProcessCollisionSectorList(CPtrList *lists) } } } - }else if(IsBodyPart(A->GetModelIndex()) && B->IsPed()){ + }else if(A->GetModelIndex() == MI_GRENADE && B->IsPed() && + A->GetPosition().z < B->GetPosition().z){ skipCollision = true; - }else if(A->IsPed() && IsBodyPart(B->GetModelIndex())){ + }else if(B->GetModelIndex() == MI_GRENADE && A->IsPed() && + B->GetPosition().z < A->GetPosition().z){ skipCollision = true; A->bSkipLineCol = true; }else if(A->IsPed() && Aped->m_pCollidingEntity == B){ skipCollision = true; - if(!Aped->bKnockedUpIntoAir) + if(!Aped->bKnockedUpIntoAir || Aped->b158_4) A->bSkipLineCol = true; }else if(B->IsPed() && Bped->m_pCollidingEntity == A){ skipCollision = true; @@ -1469,7 +1615,11 @@ CPhysical::ProcessCollisionSectorList(CPtrList *lists) if(!A->bUsesCollision || skipCollision){ B->m_scanCode = CWorld::GetCurrentScanCode(); - A->ProcessEntityCollision(B, aColPoints); + numCollisions = A->ProcessEntityCollision(B, aColPoints); + if(A->bJustCheckCollision && numCollisions > 0) + return true; + if(numCollisions == 0 && A == (CEntity*)FindPlayerPed() && Aped->m_pCollidingEntity == B) + Aped->m_pCollidingEntity = nil; }else if(B->IsBuilding() || B->bIsStuck || B->bInfiniteMass || altcollision){ // This is the case where B doesn't move @@ -1481,6 +1631,7 @@ CPhysical::ProcessCollisionSectorList(CPtrList *lists) CVector moveSpeed = { 0.0f, 0.0f, 0.0f }; CVector turnSpeed = { 0.0f, 0.0f, 0.0f }; + float maxImpulseA = 0.0f; numResponses = 0; if(A->bHasContacted){ for(i = 0; i < numCollisions; i++){ @@ -1488,20 +1639,35 @@ CPhysical::ProcessCollisionSectorList(CPtrList *lists) continue; numResponses++; + if(impulseA > maxImpulseA) maxImpulseA = impulseA; - if(impulseA > A->m_fDamageImpulse) - A->SetDamagedPieceRecord(aColPoints[i].pieceA, impulseA, B, aColPoints[i].normal); + if(A->IsVehicle()){ + if(!(((CVehicle*)A)->IsBoat() && aColPoints[i].surfaceB == SURFACE_WOOD_SOLID) && + impulseA > A->m_fDamageImpulse) + A->SetDamagedPieceRecord(aColPoints[i].pieceA, impulseA, B, aColPoints[i].normal); - float imp = impulseA; - if(A->IsVehicle() && A->GetUp().z < -0.6f && - Abs(A->m_vecMoveSpeed.x) < 0.05f && - Abs(A->m_vecMoveSpeed.y) < 0.05f) - imp *= 0.1f; + if(CSurfaceTable::GetAdhesionGroup(aColPoints[i].surfaceB) == ADHESIVE_SAND) + aColPoints[i].surfaceB = SURFACE_SAND; - float turnSpeedDiff = A->m_vecTurnSpeed.MagnitudeSqr(); - float moveSpeedDiff = A->m_vecMoveSpeed.MagnitudeSqr(); + float turnSpeedDiff = A->m_vecTurnSpeed.MagnitudeSqr(); + float moveSpeedDiff = A->m_vecMoveSpeed.MagnitudeSqr(); - DMAudio.ReportCollision(A, B, aColPoints[i].surfaceA, aColPoints[i].surfaceB, imp, Max(turnSpeedDiff, moveSpeedDiff)); + if(A->GetUp().z < -0.6f && + Abs(A->m_vecMoveSpeed.x) < 0.05f && + Abs(A->m_vecMoveSpeed.y) < 0.05f) + DMAudio.ReportCollision(A, B, aColPoints[i].surfaceA, aColPoints[i].surfaceB, 0.1f*impulseA, Max(turnSpeedDiff, moveSpeedDiff)); + else + DMAudio.ReportCollision(A, B, aColPoints[i].surfaceA, aColPoints[i].surfaceB, impulseA, Max(turnSpeedDiff, moveSpeedDiff)); + + }else{ + if(impulseA > A->m_fDamageImpulse) + A->SetDamagedPieceRecord(aColPoints[i].pieceA, impulseA, B, aColPoints[i].normal); + + float turnSpeedDiff = A->m_vecTurnSpeed.MagnitudeSqr(); + float moveSpeedDiff = A->m_vecMoveSpeed.MagnitudeSqr(); + + DMAudio.ReportCollision(A, B, aColPoints[i].surfaceA, aColPoints[i].surfaceB, impulseA, Max(turnSpeedDiff, moveSpeedDiff)); + } } }else{ for(i = 0; i < numCollisions; i++){ @@ -1509,39 +1675,52 @@ CPhysical::ProcessCollisionSectorList(CPtrList *lists) continue; numResponses++; - - if(impulseA > A->m_fDamageImpulse) - A->SetDamagedPieceRecord(aColPoints[i].pieceA, impulseA, B, aColPoints[i].normal); - - float imp = impulseA; - if(A->IsVehicle() && A->GetUp().z < -0.6f && - Abs(A->m_vecMoveSpeed.x) < 0.05f && - Abs(A->m_vecMoveSpeed.y) < 0.05f) - imp *= 0.1f; - - float turnSpeedDiff = A->m_vecTurnSpeed.MagnitudeSqr(); - float moveSpeedDiff = A->m_vecMoveSpeed.MagnitudeSqr(); - - DMAudio.ReportCollision(A, B, aColPoints[i].surfaceA, aColPoints[i].surfaceB, imp, Max(turnSpeedDiff, moveSpeedDiff)); - + if(impulseA > maxImpulseA) maxImpulseA = impulseA; float adhesion = CSurfaceTable::GetAdhesiveLimit(aColPoints[i]) / numCollisions; - if(A->GetModelIndex() == MI_RCBANDIT) - adhesion *= 0.2f; -// TODO(MIAMI): check this - else if(A->IsVehicle() && ((CVehicle*)A)->IsBoat()){ - if(aColPoints[i].normal.z > 0.6f){ - if(CSurfaceTable::GetAdhesionGroup(aColPoints[i].surfaceB) == ADHESIVE_LOOSE) - adhesion *= 3.0f; - }else + if(A->IsVehicle()){ + if(((CVehicle*)A)->IsBoat() && aColPoints[i].surfaceB == SURFACE_WOOD_SOLID) adhesion = 0.0f; - }else if(A->IsVehicle()){ - if(A->GetStatus() == STATUS_WRECKED) + else if(impulseA > A->m_fDamageImpulse) + A->SetDamagedPieceRecord(aColPoints[i].pieceA, impulseA, B, aColPoints[i].normal); + + if(CSurfaceTable::GetAdhesionGroup(aColPoints[i].surfaceB) == ADHESIVE_SAND) + aColPoints[i].surfaceB = SURFACE_SAND; + + float turnSpeedDiff = A->m_vecTurnSpeed.MagnitudeSqr(); + float moveSpeedDiff = A->m_vecMoveSpeed.MagnitudeSqr(); + + if(A->GetUp().z < -0.6f && + Abs(A->m_vecMoveSpeed.x) < 0.05f && + Abs(A->m_vecMoveSpeed.y) < 0.05f) + DMAudio.ReportCollision(A, B, aColPoints[i].surfaceA, aColPoints[i].surfaceB, 0.1f*impulseA, Max(turnSpeedDiff, moveSpeedDiff)); + else + DMAudio.ReportCollision(A, B, aColPoints[i].surfaceA, aColPoints[i].surfaceB, impulseA, Max(turnSpeedDiff, moveSpeedDiff)); + + + if(A->GetModelIndex() == MI_RCBANDIT) + adhesion *= 0.2f; + else if(((CVehicle*)A)->IsBoat()){ + if(aColPoints[i].normal.z > 0.6f){ + if(CSurfaceTable::GetAdhesionGroup(aColPoints[i].surfaceB) == ADHESIVE_LOOSE || + CSurfaceTable::GetAdhesionGroup(aColPoints[i].surfaceB) == ADHESIVE_SAND) + adhesion *= 3.0f; + }else + adhesion = 0.0f; + }else if(A->GetStatus() == STATUS_WRECKED) adhesion *= 3.0f; else if(A->GetUp().z > 0.3f) adhesion = 0.0f; else adhesion *= Min(5.0f, 0.03f*impulseA + 1.0f); + }else{ + if(impulseA > A->m_fDamageImpulse) + A->SetDamagedPieceRecord(aColPoints[i].pieceA, impulseA, B, aColPoints[i].normal); + + float turnSpeedDiff = A->m_vecTurnSpeed.MagnitudeSqr(); + float moveSpeedDiff = A->m_vecMoveSpeed.MagnitudeSqr(); + + DMAudio.ReportCollision(A, B, aColPoints[i].surfaceA, aColPoints[i].surfaceB, impulseA, Max(turnSpeedDiff, moveSpeedDiff)); } if(A->ApplyFriction(adhesion, aColPoints[i])) @@ -1560,7 +1739,13 @@ CPhysical::ProcessCollisionSectorList(CPtrList *lists) A->m_vecMoveFriction.y += moveSpeed.y * -0.3f / numCollisions; A->m_vecTurnFriction += turnSpeed * -0.3f / numCollisions; } - return true; + + if(B->IsObject() && Bobj->m_nCollisionDamageEffect && maxImpulseA > 20.0f) + Bobj->ObjectDamage(maxImpulseA); + + if(!CWorld::bSecondShift) + return true; + ret = true; } }else{ @@ -1691,18 +1876,34 @@ CPhysical::ProcessCollisionSectorList(CPtrList *lists) } if(B->IsPed() && A->IsVehicle() && - (!Bped->IsPlayer() || B->bHasHitWall && A->m_vecMoveSpeed.MagnitudeSqr() > 0.0025f)) + (!Bped->IsPlayer() || B->bHasHitWall && A->m_vecMoveSpeed.MagnitudeSqr() > SQR(0.05f))) Bped->KillPedWithCar((CVehicle*)A, maxImpulseB); else if(B->GetModelIndex() == MI_TRAIN && A->IsPed() && (!Aped->IsPlayer() || A->bHasHitWall)) Aped->KillPedWithCar((CVehicle*)B, maxImpulseA*2.0f); else if(B->IsObject() && B->bUsesCollision && A->IsVehicle()){ + // BUG? not impulseA? if(Bobj->m_nCollisionDamageEffect && maxImpulseB > 20.0f) Bobj->ObjectDamage(maxImpulseB); + else if(Bobj->m_nCollisionDamageEffect >= DAMAGE_EFFECT_SMASH_COMPLETELY){ + CMatrix inv; + CVector size = CModelInfo::GetModelInfo(B->GetModelIndex())->GetColModel()->boundingBox.GetSize(); + size = B->GetMatrix() * size; + if(size.z < B->GetPosition().z || + (Invert(A->GetMatrix(), inv) * size).z < 0.0f) + Bobj->ObjectDamage(50.0f); + } }else if(A->IsObject() && A->bUsesCollision && B->IsVehicle()){ - // BUG? not impulseA? if(Aobj->m_nCollisionDamageEffect && maxImpulseB > 20.0f) Aobj->ObjectDamage(maxImpulseB); + else if(Aobj->m_nCollisionDamageEffect >= DAMAGE_EFFECT_SMASH_COMPLETELY){ + CMatrix inv; + CVector size = CModelInfo::GetModelInfo(A->GetModelIndex())->GetColModel()->boundingBox.GetSize(); + size = A->GetMatrix() * size; + if(size.z < A->GetPosition().z || + (Invert(B->GetMatrix(), inv) * size).z < 0.0f) + Aobj->ObjectDamage(50.0f); + } } if(B->GetStatus() == STATUS_SIMPLE){ @@ -1711,13 +1912,15 @@ CPhysical::ProcessCollisionSectorList(CPtrList *lists) CCarCtrl::SwitchVehicleToRealPhysics((CVehicle*)B); } - return true; + if(!CWorld::bSecondShift) + return true; + ret = true; } } } - return false; + return ret; } bool @@ -1746,6 +1949,8 @@ CPhysical::CheckCollision_SimpleCar(void) return false; } +float PHYSICAL_SHIFT_SPEED_DAMP = 0.707f; + void CPhysical::ProcessShift(void) { @@ -1755,6 +1960,13 @@ CPhysical::ProcessShift(void) bIsInSafePosition = true; RemoveAndAdd(); }else{ + CPhysical *surf; + if(bHasHitWall && IsPed() && (surf = ((CPed*)this)->m_pCurrentPhysSurface, surf == nil || !surf->bInfiniteMass || surf->m_phy_flagA08) || + CWorld::bSecondShift){ + m_vecMoveSpeed *= Pow(PHYSICAL_SHIFT_SPEED_DAMP, CTimer::GetTimeStep()); + m_vecTurnSpeed *= Pow(PHYSICAL_SHIFT_SPEED_DAMP, CTimer::GetTimeStep()); + } + CMatrix matrix(GetMatrix()); ApplyMoveSpeed(); ApplyTurnSpeed(); @@ -1766,17 +1978,25 @@ CPhysical::ProcessShift(void) m_bIsVehicleBeingShifted = true; CEntryInfoNode *node; - bool hasshifted = false; // whatever that means... + bool hasshifted = false; for(node = m_entryInfoList.first; node; node = node->next) hasshifted |= ProcessShiftSectorList(node->sector->m_lists); m_bIsVehicleBeingShifted = false; if(hasshifted){ CWorld::AdvanceCurrentScanCode(); + bool hadCollision = false; for(node = m_entryInfoList.first; node; node = node->next) if(ProcessCollisionSectorList(node->sector->m_lists)){ - GetMatrix() = matrix; - return; + if(!CWorld::bSecondShift){ + GetMatrix() = matrix; + return; + } + hadCollision = true; } + if(hadCollision){ + GetMatrix() = matrix; + return; + } } bIsStuck = false; bIsInSafePosition = true; @@ -1788,6 +2008,9 @@ CPhysical::ProcessShift(void) // x is the number of units (m) we would like to step #define NUMSTEPS(x) ceil(Sqrt(distSq) * (1.0f/(x))) +float HIGHSPEED_ELASTICITY_MULT_PED = 2.0f; +float HIGHSPEED_ELASTICITY_MULT_COPCAR = 2.0f; + void CPhysical::ProcessCollision(void) { @@ -1819,31 +2042,78 @@ CPhysical::ProcessCollision(void) // Save current state CMatrix savedMatrix(GetMatrix()); + float savedElasticity = m_fElasticity; + CVector savedMoveSpeed = m_vecMoveSpeed; float savedTimeStep = CTimer::GetTimeStep(); int8 n = 1; // The number of steps we divide the time step into float step = 0.0f; // divided time step - float distSq = GetDistanceSq(); + float distSq = m_vecMoveSpeed.MagnitudeSqr() * sq(CTimer::GetTimeStep()); - if(IsPed() && (distSq >= sq(0.2f) || ped->IsPlayer())){ - if(ped->IsPlayer()) - n = Max(NUMSTEPS(0.2f), 2.0f); - else - n = NUMSTEPS(0.3f); + if(IsPed() && (distSq >= sq(0.3f) || ped->IsPlayer())){ + if(ped->IsPlayer()){ + if(ped->m_pCurrentPhysSurface) + n = Max(NUMSTEPS(0.15f), 4.0f); + else + n = Max(NUMSTEPS(0.3f), 2.0f); + }else + n = NUMSTEPS(0.45f); step = savedTimeStep / n; + if(!ped->IsPlayer()) + ped->m_fElasticity *= HIGHSPEED_ELASTICITY_MULT_PED; }else if(IsVehicle() && distSq >= sq(0.4f)){ if(GetStatus() == STATUS_PLAYER) n = NUMSTEPS(0.2f); else n = distSq > 0.32f ? NUMSTEPS(0.3f) : NUMSTEPS(0.4f); step = savedTimeStep / n; - }else if(IsObject()){ + + CVector bbox = GetColModel()->boundingBox.GetSize(); + float relDistX = Abs(DotProduct(m_vecMoveSpeed, GetRight())) * CTimer::GetTimeStep() / bbox.x; + float relDistY = Abs(DotProduct(m_vecMoveSpeed, GetForward())) * CTimer::GetTimeStep() / bbox.y; + float relDistZ = Abs(DotProduct(m_vecMoveSpeed, GetUp())) * CTimer::GetTimeStep() / bbox.z; + if(Max(relDistX, Max(relDistY, relDistZ)) < 1.0f){ + // check if we can get away with simplified processing + + ApplyMoveSpeed(); + ApplyTurnSpeed(); + GetMatrix().Reorthogonalise(); + bSkipLineCol = false; + m_bIsVehicleBeingShifted = false; + + bJustCheckCollision = true; + bUsesCollision = false; + if(!CheckCollision()){ + bJustCheckCollision = false; + bUsesCollision = true; + if(IsVehicle()) + ((CVehicle*)this)->bVehicleColProcessed = true; + + bHitByTrain = false; + m_fDistanceTravelled = (GetPosition() - savedMatrix.GetPosition()).Magnitude(); + bSkipLineCol = false; + + bIsStuck = false; + bIsInSafePosition = true; + m_fElasticity = savedElasticity; + RemoveAndAdd(); + return; + } + bJustCheckCollision = false; + bUsesCollision = true; + GetMatrix() = savedMatrix; + m_vecMoveSpeed = savedMoveSpeed; + if(IsVehicle() && ((CVehicle*)this)->bIsLawEnforcer) + m_fElasticity *= HIGHSPEED_ELASTICITY_MULT_COPCAR; + } + }else if(IsObject() && ((CObject*)this)->ObjectCreatedBy != TEMP_OBJECT){ int responsecase = ((CObject*)this)->m_nSpecialCollisionResponseCases; if(responsecase == COLLRESPONSE_LAMPOST){ CVector speedUp = { 0.0f, 0.0f, 0.0f }; CVector speedDown = { 0.0f, 0.0f, 0.0f }; - speedUp.z = GetBoundRadius(); - speedDown.z = -speedUp.z; + CColModel *colModel = GetColModel(); + speedUp.z = colModel->boundingBox.max.z; + speedDown.z = colModel->boundingBox.min.z; speedUp = Multiply3x3(GetMatrix(), speedUp); speedDown = Multiply3x3(GetMatrix(), speedDown); speedUp = GetSpeed(speedUp); @@ -1883,6 +2153,7 @@ CPhysical::ProcessCollision(void) savedMatrix.GetPosition().z = GetPosition().z; GetMatrix() = savedMatrix; CTimer::SetTimeStep(savedTimeStep); + m_fElasticity = savedElasticity; return; } if(IsPed() && m_vecMoveSpeed.z == 0.0f && @@ -1900,7 +2171,7 @@ CPhysical::ProcessCollision(void) car->m_aSuspensionSpringRatio[2] = 1.0f; car->m_aSuspensionSpringRatio[3] = 1.0f; }else if(veh->m_vehType == VEHICLE_TYPE_BIKE){ - assert(0 && "TODO - but unused"); + assert(0 && "TODO(MIAMI)"); } } } @@ -1913,11 +2184,14 @@ CPhysical::ProcessCollision(void) if(!m_vecMoveSpeed.IsZero() || !m_vecTurnSpeed.IsZero() || bHitByTrain || - GetStatus() == STATUS_PLAYER || IsPed() && ped->IsPlayer()){ + GetStatus() == STATUS_PLAYER || + IsVehicle() && ((CVehicle*)this)->bRestingOnPhysical || + IsPed() && ped->IsPlayer()){ if(IsVehicle()) ((CVehicle*)this)->bVehicleColProcessed = true; if(CheckCollision()){ GetMatrix() = savedMatrix; + m_fElasticity = savedElasticity; return; } } @@ -1927,5 +2201,6 @@ CPhysical::ProcessCollision(void) bIsStuck = false; bIsInSafePosition = true; + m_fElasticity = savedElasticity; RemoveAndAdd(); } diff --git a/src/entities/Physical.h b/src/entities/Physical.h index ce02e463..926b9762 100644 --- a/src/entities/Physical.h +++ b/src/entities/Physical.h @@ -18,8 +18,7 @@ public: // The not properly indented fields haven't been checked properly yet int32 m_audioEntityId; - float unk1; - CTreadable *m_treadable[2]; // car and ped + float m_phys_unused1; uint32 m_nLastTimeCollided; CVector m_vecMoveSpeed; // velocity CVector m_vecTurnSpeed; // angular velocity @@ -37,10 +36,9 @@ public: CEntryInfoList m_entryInfoList; CPtrNode *m_movingListNode; - char field_EC; + int8 m_phys_unused2; uint8 m_nStaticFrames; uint8 m_nCollisionRecords; - bool m_bIsVehicleBeingShifted; CEntity *m_aCollisionRecords[PHYSICAL_MAX_COLLISIONRECORDS]; float m_fDistanceTravelled; @@ -54,12 +52,17 @@ public: uint8 bIsHeavy : 1; uint8 bAffectedByGravity : 1; uint8 bInfiniteMass : 1; + uint8 m_phy_flagA08 : 1; uint8 bIsInWater : 1; - uint8 m_phy_flagA10 : 1; // unused uint8 m_phy_flagA20 : 1; // unused uint8 bHitByTrain : 1; uint8 bSkipLineCol : 1; + uint8 bIsFrozen : 1; + uint8 bDontLoadCollision : 1; + uint8 m_bIsVehicleBeingShifted : 1; // wrong name - also used on but never set for peds + uint8 bJustCheckCollision : 1; // just see if there is a collision + uint8 m_nSurfaceTouched; int8 m_nZoneLevel; @@ -86,7 +89,6 @@ public: void RemoveRefsToEntity(CEntity *ent); static void PlacePhysicalRelativeToOtherPhysical(CPhysical *other, CPhysical *phys, CVector localPos); - float GetDistanceSq(void) { return m_vecMoveSpeed.MagnitudeSqr() * sq(CTimer::GetTimeStep()); } // get speed of point p relative to entity center CVector GetSpeed(const CVector &r); CVector GetSpeed(void) { return GetSpeed(CVector(0.0f, 0.0f, 0.0f)); } @@ -94,7 +96,7 @@ public: return 1.0f / (CrossProduct(pos, dir).MagnitudeSqr()/m_fTurnMass + 1.0f/m_fMass); } - float GetMassTime(const CVector &pos, const CVector &dir, float t) { + float GetMassTweak(const CVector &pos, const CVector &dir, float t) { return 1.0f / (CrossProduct(pos, dir).MagnitudeSqr()/(m_fTurnMass*t) + 1.0f/(m_fMass*t)); } @@ -156,11 +158,13 @@ public: void ApplyFrictionTurnForce(const CVector &j, const CVector &p) { ApplyFrictionTurnForce(j.x, j.y, j.z, p.x, p.y, p.z); } // springRatio: 1.0 fully extended, 0.0 fully compressed bool ApplySpringCollision(float springConst, CVector &springDir, CVector &point, float springRatio, float bias); + bool ApplySpringCollisionAlt(float springConst, CVector &springDir, CVector &point, float springRatio, float bias, CVector &forceDir); bool ApplySpringDampening(float damping, CVector &springDir, CVector &point, CVector &speed); void ApplyGravity(void); void ApplyFriction(void); void ApplyAirResistance(void); bool ApplyCollision(CPhysical *B, CColPoint &colpoint, float &impulseA, float &impulseB); + bool ApplyCollision(CColPoint &colpoint, float &impulse); bool ApplyCollisionAlt(CEntity *B, CColPoint &colpoint, float &impulse, CVector &moveSpeed, CVector &turnSpeed); bool ApplyFriction(CPhysical *B, float adhesiveLimit, CColPoint &colpoint); bool ApplyFriction(float adhesiveLimit, CColPoint &colpoint); diff --git a/src/fakerw/fake.cpp b/src/fakerw/fake.cpp index 50d12b2f..71646020 100644 --- a/src/fakerw/fake.cpp +++ b/src/fakerw/fake.cpp @@ -470,7 +470,7 @@ RwBool RwRenderStateSet(RwRenderState state, void *value) uint32 uival = (uintptr)value; uint32 fog; switch(state){ - case rwRENDERSTATETEXTURERASTER: SetRenderState(TEXTURERASTER, uival); return true; + case rwRENDERSTATETEXTURERASTER: SetRenderStatePtr(TEXTURERASTER, value); return true; case rwRENDERSTATETEXTUREADDRESS: SetRenderState(TEXTUREADDRESS, uival); return true; case rwRENDERSTATETEXTUREADDRESSU: SetRenderState(TEXTUREADDRESSU, uival); return true; case rwRENDERSTATETEXTUREADDRESSV: SetRenderState(TEXTUREADDRESSV, uival); return true; diff --git a/src/math/Matrix.h b/src/math/Matrix.h index b7e055c5..1d26cc20 100644 --- a/src/math/Matrix.h +++ b/src/math/Matrix.h @@ -78,7 +78,8 @@ public: return *this; } - CVector &GetPosition(void){ return *(CVector*)&m_matrix.pos; } + const CVector &GetPosition(void) const { return *(CVector*)&m_matrix.pos; } + CVector& GetPosition(void) { return *(CVector*)&m_matrix.pos; } CVector &GetRight(void) { return *(CVector*)&m_matrix.right; } CVector &GetForward(void) { return *(CVector*)&m_matrix.up; } CVector &GetUp(void) { return *(CVector*)&m_matrix.at; } diff --git a/src/math/Vector2D.h b/src/math/Vector2D.h index 0885a5d2..7bfccae6 100644 --- a/src/math/Vector2D.h +++ b/src/math/Vector2D.h @@ -11,9 +11,7 @@ public: float Magnitude(void) const { return Sqrt(x*x + y*y); } float MagnitudeSqr(void) const { return x*x + y*y; } - void Normalise(void); - - void NormaliseSafe(void) { + void Normalise(void) { float sq = MagnitudeSqr(); if(sq > 0.0f){ float invsqrt = RecipSqrt(sq); diff --git a/src/math/math.cpp b/src/math/math.cpp index eeb9d3fa..e11d048c 100644 --- a/src/math/math.cpp +++ b/src/math/math.cpp @@ -4,19 +4,6 @@ // TODO: move more stuff into here -void -CVector2D::Normalise(void) -{ - float sq = MagnitudeSqr(); - assert(sq != 0.0f); // just be safe here - //if(sq > 0.0f){ - float invsqrt = RecipSqrt(sq); - x *= invsqrt; - y *= invsqrt; - //}else - // x = 1.0f; -} - void CMatrix::SetRotate(float xAngle, float yAngle, float zAngle) { diff --git a/src/modelinfo/ModelIndices.cpp b/src/modelinfo/ModelIndices.cpp index 9a6a74d0..056c3733 100644 --- a/src/modelinfo/ModelIndices.cpp +++ b/src/modelinfo/ModelIndices.cpp @@ -3,14 +3,14 @@ #include "General.h" #include "ModelIndices.h" -#define X(name, var, addr) int16 var; +#define X(name, var) int16 var; MODELINDICES #undef X void InitModelIndices(void) { -#define X(name, var, addr) var = -1; +#define X(name, var) var = -1; MODELINDICES #undef X } @@ -18,7 +18,7 @@ InitModelIndices(void) void MatchModelString(const char *modelname, int16 id) { -#define X(name, var, addr) \ +#define X(name, var) \ if(!CGeneral::faststrcmp(name, modelname)){ \ var = id; \ return; \ diff --git a/src/modelinfo/ModelIndices.h b/src/modelinfo/ModelIndices.h index a21da7d3..e7285b2f 100644 --- a/src/modelinfo/ModelIndices.h +++ b/src/modelinfo/ModelIndices.h @@ -3,166 +3,144 @@ #include "ModelInfo.h" #define MODELINDICES \ - X("fire_hydrant", MI_FIRE_HYDRANT, 0x5F5A00) \ - X("bagelstnd02", MI_BAGELSTAND2, 0x5F59FC) \ - X("fish01", MI_FISHSTALL01, 0x5F59EC) \ - X("fishstall02", MI_FISHSTALL02, 0x5F59F0) \ - X("fishstall03", MI_FISHSTALL03, 0x5F59F4) \ - X("fishstall04", MI_FISHSTALL04, 0x5F59F8) \ - X("taxisign", MI_TAXISIGN, 0x5F59E8) \ - X("phonesign", MI_PHONESIGN, 0x5F59E4) \ - X("noparkingsign1", MI_NOPARKINGSIGN1, 0x5F59E0) \ - X("bussign1", MI_BUSSIGN1, 0x5F59DC) \ - X("roadworkbarrier1", MI_ROADWORKBARRIER1, 0x5F59D8) \ - X("dump1", MI_DUMP1, 0x5F59D4) \ - X("trafficcone", MI_TRAFFICCONE, 0x5F59D0) \ - X("newsstand1", MI_NEWSSTAND, 0x5F59CC) \ - X("postbox1", MI_POSTBOX1, 0x5F59C8) \ - X("bin1", MI_BIN, 0x5F59C4) \ - X("wastebin", MI_WASTEBIN, 0x5F59C0) \ - X("phonebooth1", MI_PHONEBOOTH1, 0x5F59BC) \ - X("parkingmeter", MI_PARKINGMETER, 0x5F59B8) \ - X("trafficlight1", MI_TRAFFICLIGHTS, 0x5F5958) \ - X("lamppost1", MI_SINGLESTREETLIGHTS1, 0x5F595C) \ - X("lamppost2", MI_SINGLESTREETLIGHTS2, 0x5F5960) \ - X("lamppost3", MI_SINGLESTREETLIGHTS3, 0x5F5964) \ - X("doublestreetlght1", MI_DOUBLESTREETLIGHTS, 0x5F5968) \ - X("rd_Road2A10", MI_ROADSFORROADBLOCKSSTART, 0x5F596C) \ - X("rd_Road1A30", MI_ROADSFORROADBLOCKSEND, 0x5F5970) \ - X("veg_tree1", MI_TREE1, 0x5F5974) \ - X("veg_tree3", MI_TREE2, 0x5F5978) \ - X("veg_treea1", MI_TREE3, 0x5F597C) \ - X("veg_treenew01", MI_TREE4, 0x5F5980) \ - X("veg_treenew05", MI_TREE5, 0x5F5984) \ - X("veg_treeb1", MI_TREE6, 0x5F5988) \ - X("veg_treenew10", MI_TREE7, 0x5F598C) \ - X("veg_treea3", MI_TREE8, 0x5F5990) \ - X("veg_treenew09", MI_TREE9, 0x5F5994) \ - X("veg_treenew08", MI_TREE10, 0x5F5998) \ - X("veg_treenew03", MI_TREE11, 0x5F599C) \ - X("veg_treenew16", MI_TREE12, 0x5F59A0) \ - X("veg_treenew17", MI_TREE13, 0x5F59A4) \ - X("veg_treenew06", MI_TREE14, 0x5F59A8) \ - X("doc_crane_cab", MODELID_CRANE_1, 0x5F59AC) \ - X("cranetopb", MODELID_CRANE_2, 0x5F59B0) \ - X("cranetopa", MODELID_CRANE_3, 0x5F59B4) \ - X("package1", MI_COLLECTABLE1, 0x5F5A04) \ - X("Money", MI_MONEY, 0x5F5A08) \ - X("barrel1", MI_CARMINE, 0x5F5A0C) \ - /*X("oddjgaragdoor", MI_GARAGEDOOR1, 0x5F5A10)*/ \ - X("dk_paynspraydoor", MI_GARAGEDOOR2, 0x5F5A14) \ - X("dk_waretankdoor1", MI_GARAGEDOOR3, 0x5F5A18) \ - X("hav_garagedoor1", MI_GARAGEDOOR4, 0x5F5A1C) \ - X("hav_garagedoor02", MI_GARAGEDOOR5, 0x5F5A20) \ - X("hav_garagedoor03", MI_GARAGEDOOR6, 0x5F5A24) \ - X("hav_garagedoor04", MI_GARAGEDOOR7, 0x5F5A28) \ - X("lh_showdoor03", MI_GARAGEDOOR9, 0x5F5A2C) \ - X("lh_showdoor1", MI_GARAGEDOOR10, 0x5F5A30) \ - X("lhtankdoor", MI_GARAGEDOOR11, 0x5F5A34) \ - X("nbtgardoor", MI_GARAGEDOOR12, 0x5F5A38) \ - X("dk_camjonesdoor", MI_GARAGEDOOR13, 0x5F5A3C) \ - X("nbtgardoor02", MI_GARAGEDOOR14, 0x5F5A40) \ - X("dt_savedra", MI_GARAGEDOOR15, 0x5F5A44) \ - X("dt_savedrb", MI_GARAGEDOOR16, 0x5F5A48) \ - /*X("dk_bombdoor", MI_GARAGEDOOR17, 0x5F5A4C)*/ \ - X("dk_bombdoor", MI_GARAGEDOOR18, 0x5F5A50) \ - X("haiwshpnsdoor", MI_GARAGEDOOR19, 0x5F5A54) \ - X("wshpnsdoor", MI_GARAGEDOOR20, 0x5F5A58) \ - X("nbecpnsdoor", MI_GARAGEDOOR21, 0x5F5A5C) \ - X("nbtgardoor03", MI_GARAGEDOOR22, 0x5F5A60) \ - X("dt_savedrc", MI_GARAGEDOOR23, 0x5F5A64) \ - X("dt_savedrd", MI_GARAGEDOOR24, 0x5F5A68) \ - X("man_frntstepGD", MI_GARAGEDOOR25, 0x5F5A6C) \ - X("svegrgedoor", MI_GARAGEDOOR26, 0x5F5A70) \ - /*X("towergaragedoor3", MI_GARAGEDOOR27, 0x5F5A74)*/ \ - /*X("plysve_gragedoor", MI_GARAGEDOOR28, 0x5F5A78)*/ \ - /*X("impexpsubgrgdoor", MI_GARAGEDOOR29, 0x5F5A7C)*/ \ - /*X("Sub_sprayshopdoor", MI_GARAGEDOOR30, 0x5F5A80)*/ \ - /*X("ind_plyrwoor", MI_GARAGEDOOR31, 0x5F5A84)*/ \ - /*X("8ballsuburbandoor", MI_GARAGEDOOR32, 0x5F5A88)*/ \ - X("barrel2", MI_NAUTICALMINE, 0x5F5A8C) \ - X("crushercrush", MI_CRUSHERBODY, 0x5F5A90) \ - X("crushertop", MI_CRUSHERLID, 0x5F5A94) \ - X("donkeymag", MI_DONKEYMAG, 0x5F5A98) \ - X("bullion", MI_BULLION, 0x5F5A9C) \ - X("floatpackge1", MI_FLOATPACKAGE1, 0x5F5AA0) \ - X("briefcase", MI_BRIEFCASE, 0x5F5AA4) \ - X("chinabanner1", MI_CHINABANNER1, 0x5F5AA8) \ - X("chinabanner2", MI_CHINABANNER2, 0x5F5AAC) \ - X("chinabanner3", MI_CHINABANNER3, 0x5F5AB0) \ - X("chinabanner4", MI_CHINABANNER4, 0x5F5AB4) \ - X("iten_chinatown5", MI_CHINABANNER5, 0x5F5AB8) \ - X("iten_chinatown7", MI_CHINABANNER6, 0x5F5ABC) \ - X("iten_chinatown3", MI_CHINABANNER7, 0x5F5AC0) \ - X("iten_chinatown2", MI_CHINABANNER8, 0x5F5AC4) \ - X("iten_chinatown4", MI_CHINABANNER9, 0x5F5AC8) \ - X("iten_washline01", MI_CHINABANNER10, 0x5F5ACC) \ - X("iten_washline02", MI_CHINABANNER11, 0x5F5AD0) \ - X("iten_washline03", MI_CHINABANNER12, 0x5F5AD4) \ - X("chinalanterns", MI_CHINALANTERN, 0x5F5AD8) \ - X("glassfx1", MI_GLASS1, 0x5F5ADC) \ - X("glassfx2", MI_GLASS2, 0x5F5AE0) \ - X("glassfx3", MI_GLASS3, 0x5F5AE4) \ - X("glassfx4", MI_GLASS4, 0x5F5AE8) \ - X("glassfx55", MI_GLASS5, 0x5F5AEC) \ - X("glassfxsub1", MI_GLASS6, 0x5F5AF0) \ - X("glassfxsub2", MI_GLASS7, 0x5F5AF4) \ - X("glassfx_composh", MI_GLASS8, 0x5F5AF8) \ - X("bridge_liftsec", MI_BRIDGELIFT, 0x5F5AFC) \ - X("bridge_liftweight", MI_BRIDGEWEIGHT, 0x5F5B00) \ - X("subbridge_lift", MI_BRIDGEROADSEGMENT, 0x5F5B04) \ - X("barrel4", MI_EXPLODINGBARREL, 0x5F5B08) \ - X("flagsitaly", MI_ITALYBANNER1, 0x5F5B0C) \ - X("adrenaline", MI_PICKUP_ADRENALINE, 0x5F5B10) \ - X("bodyarmour", MI_PICKUP_BODYARMOUR, 0x5F5B14) \ - X("info", MI_PICKUP_INFO, 0x5F5B18) \ - X("health", MI_PICKUP_HEALTH, 0x5F5B1C) \ - X("bonus", MI_PICKUP_BONUS, 0x5F5B20) \ - X("bribe", MI_PICKUP_BRIBE, 0x5F5B24) \ - X("killfrenzy", MI_PICKUP_KILLFRENZY, 0x5F5B28) \ - X("camerapickup", MI_PICKUP_CAMERA, 0x5F5B2C) \ - X("bollardlight", MI_BOLLARDLIGHT, 0x5F5B30) \ - X("magnet", MI_MAGNET, 0x5F5B34) \ - X("streetlamp1", MI_STREETLAMP1, 0x5F5B38) \ - X("streetlamp2", MI_STREETLAMP2, 0x5F5B3C) \ - X("railtrax_lo4b", MI_RAILTRACKS, 0x5F5B40) \ - X("bar_barrier10", MI_FENCE, 0x5F5B44) \ - X("bar_barrier12", MI_FENCE2, 0x5F5B48) \ - X("petrolpump", MI_PETROLPUMP, 0x5F5B4C) \ - X("bodycast", MI_BODYCAST, 0x5F5B50) \ - X("backdoor", MI_BACKDOOR, 0x5F5B54) \ - X("coffee", MI_COFFEE, 0x5F5B58) \ - X("bouy", MI_BUOY, 0x5F5B5C) \ - X("parktable1", MI_PARKTABLE, 0x5F5B60) \ - X("sbwy_tunl_start", MI_SUBWAY1, 0x5F5B64) \ - X("sbwy_tunl_bit", MI_SUBWAY2, 0x5F5B68) \ - X("sbwy_tunl_bend", MI_SUBWAY3, 0x5F5B6C) \ - X("sbwy_tunl_cstm6", MI_SUBWAY4, 0x5F5B70) \ - X("sbwy_tunl_cstm7", MI_SUBWAY5, 0x5F5B74) \ - X("sbwy_tunl_cstm8", MI_SUBWAY6, 0x5F5B78) \ - X("sbwy_tunl_cstm10", MI_SUBWAY7, 0x5F5B7C) \ - X("sbwy_tunl_cstm9", MI_SUBWAY8, 0x5F5B80) \ - X("sbwy_tunl_cstm11", MI_SUBWAY9, 0x5F5B84) \ - X("sbwy_tunl_cstm1", MI_SUBWAY10, 0x5F5B88) \ - X("sbwy_tunl_cstm2", MI_SUBWAY11, 0x5F5B8C) \ - X("sbwy_tunl_cstm4", MI_SUBWAY12, 0x5F5B90) \ - X("sbwy_tunl_cstm3", MI_SUBWAY13, 0x5F5B94) \ - X("sbwy_tunl_cstm5", MI_SUBWAY14, 0x5F5B98) \ - X("subplatform_n2", MI_SUBWAY15, 0x5F5B9C) \ - X("suby_tunl_start", MI_SUBWAY16, 0x5F5BA0) \ - X("sbwy_tunl_start2", MI_SUBWAY17, 0x5F5BA4) \ - X("indy_tunl_start", MI_SUBWAY18, 0x5F5BA8) \ - X("indsubway03", MI_SUBPLATFORM_IND, 0x5F5BAC) \ - X("comerside_subway", MI_SUBPLATFORM_COMS, 0x5F5BB0) \ - X("subplatform", MI_SUBPLATFORM_COMS2, 0x5F5BB4) \ - X("subplatform_n", MI_SUBPLATFORM_COMN, 0x5F5BB8) \ - X("Otherside_subway", MI_SUBPLATFORM_SUB, 0x5F5BBC) \ - X("subplatform_sub", MI_SUBPLATFORM_SUB2, 0x5F5BC0) \ - X("files", MI_FILES, 0x5F5BC4) \ - X("property_locked", MI_PICKUP_PROPERTY, 0x0) \ - X("property_fsale", MI_PICKUP_PROPERTY_FORSALE, 0x0) + X("fire_hydrant", MI_FIRE_HYDRANT) \ + X("phonesign", MI_PHONESIGN) \ + X("noparkingsign1", MI_NOPARKINGSIGN1) \ + X("bussign1", MI_BUSSIGN1) \ + X("roadworkbarrier1", MI_ROADWORKBARRIER1) \ + X("dump1", MI_DUMP1) \ + X("trafficcone", MI_TRAFFICCONE) \ + X("newsstand1", MI_NEWSSTAND) \ + X("postbox1", MI_POSTBOX1) \ + X("bin1", MI_BIN) \ + X("wastebin", MI_WASTEBIN) \ + X("phonebooth1", MI_PHONEBOOTH1) \ + X("parkingmeter", MI_PARKINGMETER) \ + X("parkingmeterg", MI_PARKINGMETER2) \ + X("mall_fans", MI_MALLFAN) \ + X("htl_fan_rotate_nt", MI_HOTELFAN_NIGHT) \ + X("htl_fan_rotate_dy", MI_HOTELFAN_DAY) \ + X("hotroomfan", MI_HOTROOMFAN) \ + X("trafficlight1", MI_TRAFFICLIGHTS) \ + X("MTraffic4", MI_TRAFFICLIGHTS_VERTICAL) \ + X("MTraffic1", MI_TRAFFICLIGHTS_MIAMI) \ + X("MTraffic2", MI_TRAFFICLIGHTS_TWOVERTICAL) \ + X("lamppost1", MI_SINGLESTREETLIGHTS1) \ + X("lamppost2", MI_SINGLESTREETLIGHTS2) \ + X("lamppost3", MI_SINGLESTREETLIGHTS3) \ + X("doublestreetlght1", MI_DOUBLESTREETLIGHTS) \ + X("Streetlamp1", MI_STREETLAMP1) \ + X("Streetlamp2", MI_STREETLAMP2) \ + X("veg_tree3", MI_TREE2) \ + X("veg_treea1", MI_TREE3) \ + X("veg_treeb1", MI_TREE6) \ + X("veg_treea3", MI_TREE8) \ + X("doc_crane_cab", MODELID_CRANE_1) \ + X("doc_crane_cab01", MODELID_CRANE_2) \ + X("doc_crane_cab02", MODELID_CRANE_3) \ + X("doc_crane_cab03", MODELID_CRANE_4) \ + X("boatcranelg0", MODELID_CRANE_5) \ + X("LODnetopa0", MODELID_CRANE_6) \ + X("package1", MI_COLLECTABLE1) \ + X("Money", MI_MONEY) \ + X("barrel1", MI_CARMINE) \ + X("dk_paynspraydoor", MI_GARAGEDOOR2) \ + X("dk_waretankdoor1", MI_GARAGEDOOR3) \ + X("hav_garagedoor1", MI_GARAGEDOOR4) \ + X("hav_garagedoor02", MI_GARAGEDOOR5) \ + X("hav_garagedoor03", MI_GARAGEDOOR6) \ + X("hav_garagedoor04", MI_GARAGEDOOR7) \ + X("lh_showdoor03", MI_GARAGEDOOR9) \ + X("lh_showdoor1", MI_GARAGEDOOR10) \ + X("lhtankdoor", MI_GARAGEDOOR11) \ + X("nbtgardoor", MI_GARAGEDOOR12) \ + X("dk_camjonesdoor", MI_GARAGEDOOR13) \ + X("nbtgardoor02", MI_GARAGEDOOR14) \ + X("dt_savedra", MI_GARAGEDOOR15) \ + X("dt_savedrb", MI_GARAGEDOOR16) \ + X("dk_bombdoor", MI_GARAGEDOOR18) \ + X("haiwshpnsdoor", MI_GARAGEDOOR19) \ + X("wshpnsdoor", MI_GARAGEDOOR20) \ + X("nbecpnsdoor", MI_GARAGEDOOR21) \ + X("nbtgardoor03", MI_GARAGEDOOR22) \ + X("dt_savedrc", MI_GARAGEDOOR23) \ + X("dt_savedrd", MI_GARAGEDOOR24) \ + X("man_frntstepGD", MI_GARAGEDOOR25) \ + X("svegrgedoor", MI_GARAGEDOOR26) \ + X("barrel2", MI_NAUTICALMINE) \ + X("briefcase", MI_BRIEFCASE) \ + X("wglasssmash", MI_GLASS1) \ + X("glassfx_composh", MI_GLASS8) \ + X("barrel4", MI_EXPLODINGBARREL) \ + X("adrenaline", MI_PICKUP_ADRENALINE) \ + X("bodyarmour", MI_PICKUP_BODYARMOUR) \ + X("info", MI_PICKUP_INFO) \ + X("health", MI_PICKUP_HEALTH) \ + X("bonus", MI_PICKUP_BONUS) \ + X("bribe", MI_PICKUP_BRIBE) \ + X("killfrenzy", MI_PICKUP_KILLFRENZY) \ + X("camerapickup", MI_PICKUP_CAMERA) \ + X("bigdollar", MI_PICKUP_REVENUE) \ + X("pickupsave", MI_PICKUP_SAVEGAME) \ + X("property_locked", MI_PICKUP_PROPERTY) \ + X("property_fsale", MI_PICKUP_PROPERTY_FORSALE) \ + X("clothesp", MI_PICKUP_CLOTHES) \ + X("bollardlight", MI_BOLLARDLIGHT) \ + X("bar_barrier10", MI_FENCE) \ + X("bar_barrier12", MI_FENCE2) \ + X("petrolpump", MI_PETROLPUMP) \ + X("washgaspump", MI_PETROLPUMP2) \ + X("bouy", MI_BUOY) \ + X("parktable1", MI_PARKTABLE) \ + X("lamppost1", MI_LAMPPOST1) \ + X("veg_palm04", MI_VEG_PALM01) \ + X("veg_palwee02", MI_VEG_PALM02) \ + X("veg_palmkbb11", MI_VEG_PALM03) \ + X("veg_palmkb4", MI_VEG_PALM04) \ + X("veg_palm02", MI_VEG_PALM05) \ + X("veg_palmkb3", MI_VEG_PALM06) \ + X("veg_palmbig14", MI_VEG_PALM07) \ + X("veg_palm01", MI_VEG_PALM08) \ + X("mlamppost", MI_MLAMPPOST) \ + X("roadworkbarrier1", MI_BARRIER1) \ + X("littleha_police", MI_LITTLEHA_POLICE) \ + X("telgrphpole02", MI_TELPOLE02) \ + X("trafficlight1", MI_TRAFFICLIGHT01) \ + X("parkbench1", MI_PARKBENCH) \ + X("plc_stinger", MI_PLC_STINGER) \ + X("od_lightbeam", MI_LIGHTBEAM) \ + X("ap_radar1_01", MI_AIRPORTRADAR) \ + X("rcbomb", MI_RCBOMB) \ + X("beachball", MI_BEACHBALL) \ + X("sandcastle1", MI_SANDCASTLE1) \ + X("sandcastle2", MI_SANDCASTLE2) \ + X("jellyfish", MI_JELLYFISH) \ + X("jellyfish01", MI_JELLYFISH01) \ + X("fish1single", MI_FISH1SINGLE) \ + X("fish1s", MI_FISH1S) \ + X("fish2single", MI_FISH2SINGLE) \ + X("fish2s", MI_FISH2S) \ + X("fish3single", MI_FISH3SINGLE) \ + X("fish3s", MI_FISH3S) \ + X("turtle", MI_TURTLE) \ + X("dolphin", MI_DOLPHIN) \ + X("shark", MI_SHARK) \ + X("submarine", MI_SUBMARINE) \ + X("Esc_step", MI_ESCALATORSTEP) \ + X("lounge_wood_up", MI_LOUNGE_WOOD_UP) \ + X("lounge_towel_up", MI_LOUNGE_TOWEL_UP) \ + X("lounge_wood_dn", MI_LOUNGE_WOOD_DN) \ + X("lotion", MI_LOTION) \ + X("beachtowel01", MI_BEACHTOWEL01) \ + X("beachtowel02", MI_BEACHTOWEL02) \ + X("beachtowel03", MI_BEACHTOWEL03) \ + X("beachtowel04", MI_BEACHTOWEL04) \ + X("blimp_night", MI_BLIMP_NIGHT) \ + X("blimp_day", MI_BLIMP_DAY) \ + X("yt_main_body", MI_YT_MAIN_BODY) \ + X("yt_main_body2", MI_YT_MAIN_BODY2) -#define X(name, var, addr) extern int16 var; +#define X(name, var) extern int16 var; MODELINDICES #undef X @@ -180,8 +158,25 @@ enum MI_MALE01, MI_TAXI_D = 28, // HMOCA - MI_GANG01 = 83, // CBa - MI_VICE1 = 97, + + MI_WFOGO = 63, + MI_WMOGO = 64, + + MI_CBA = 83, + MI_CBB, + MI_HNA, + MI_HNB, + MI_SGA, + MI_SGB, + MI_CLA, + MI_CLB, + MI_GDA, + MI_GDB, + MI_BKA, + MI_BKB, + MI_PGA, + MI_PGB, + MI_VICE1, MI_VICE2, MI_VICE3, MI_VICE4, @@ -192,90 +187,10 @@ enum MI_WFYG2 = 106, // last regular ped MI_SPECIAL01 = 109, MI_SPECIAL21 = 129, -/* - MI_TAXI_D, - MI_PIMP, - MI_GANG01, - MI_GANG02, - MI_GANG03, - MI_GANG04, - MI_GANG05, - MI_GANG06, - MI_GANG07, - MI_GANG08, - MI_GANG09, - MI_GANG10, - MI_GANG11, - MI_GANG12, - MI_GANG13, - MI_GANG14, - MI_CRIMINAL01, - MI_CRIMINAL02, - MI_SPECIAL01, - MI_SPECIAL02, - MI_SPECIAL03, - MI_SPECIAL04, - MI_MALE02, - MI_MALE03, - MI_FATMALE01, - MI_FATMALE02, - MI_FEMALE01, - MI_FEMALE02, - MI_FEMALE03, - MI_FATFEMALE01, - MI_FATFEMALE02, - MI_PROSTITUTE, - MI_PROSTITUTE2, - MI_P_MAN1, - MI_P_MAN2, - MI_P_WOM1, - MI_P_WOM2, - MI_CT_MAN1, - MI_CT_MAN2, - MI_CT_WOM1, - MI_CT_WOM2, - MI_LI_MAN1, - MI_LI_MAN2, - MI_LI_WOM1, - MI_LI_WOM2, - MI_DOCKER1, - MI_DOCKER2, - MI_SCUM_MAN, - MI_SCUM_WOM, - MI_WORKER1, - MI_WORKER2, - MI_B_MAN1, - MI_B_MAN2, - MI_B_MAN3, - MI_B_WOM1, - MI_B_WOM2, - MI_B_WOM3, - MI_MOD_MAN, - MI_MOD_WOM, - MI_ST_MAN, - MI_ST_WOM, - MI_FAN_MAN1, - MI_FAN_MAN2, - MI_FAN_WOM, - MI_HOS_MAN, - MI_HOS_WOM, - MI_CONST1, - MI_CONST2, - MI_SHOPPER1, - MI_SHOPPER2, - MI_SHOPPER3, - MI_STUD_MAN, - MI_STUD_WOM, - MI_CAS_MAN, - MI_CAS_WOM, - MI_BUSKER1, - MI_BUSKER2, - MI_BUSKER3, - MI_BUSKER4, - // three more peds possible -*/ - MI_FIRST_VEHICLE = 130, + MI_LAST_PED = MI_SPECIAL21, + MI_FIRST_VEHICLE, + MI_LANDSTAL = MI_FIRST_VEHICLE, MI_IDAHO, MI_STINGER, @@ -387,21 +302,35 @@ enum MI_TRAIN = -1, MI_DODO = -2, - MI_BASEBALL_BAT = 264, + MI_GOLFCLUB = 261, + MI_NIGHTSTICK, + MI_KNIFE, + MI_BASEBALL_BAT, MI_GRENADE = 270, - MI_MOLOTOV = 272, - MI_MISSILE = 273, - MI_COLT = 274, - MI_AK47 = 276, - MI_SHOTGUN = 279, - MI_M16 = 280, - MI_UZI = 282, - MI_MP5 = 284, - MI_SNIPER = 285, - MI_ROCKETLAUNCHER = 287, - MI_FLAMETHROWER = 288, - MI_BOMB = 291, - MI_FINGERS = 293, + MI_TEARGAS, + MI_MOLOTOV, + MI_MISSILE, + MI_COLT45, + MI_PYTHON, + MI_RUGER, + MI_SHOTGUN, + MI_SPAS12_SHOTGUN, + MI_STUBBY_SHOTGUN, + MI_M4, + MI_TEC9, + MI_UZI, + MI_SILENCEDINGRAM, + MI_MP5, + MI_SNIPERRIFLE, + MI_LASERSCOPE, + MI_ROCKETLAUNCHER, + MI_FLAMETHROWER, + MI_M60, + MI_MINIGUN, + MI_BOMB, + MI_CAMERA, + MI_FINGERS, + MI_MINIGUN2, MI_CUTOBJ01 = 295, MI_CUTOBJ02, @@ -419,9 +348,8 @@ enum MI_BODYPARTB, MI_AIRTRAIN_VLO = 257, -// MI_LOPOLYGUY, - NUM_DEFAULT_MODELS = 300 // MIAMI + NUM_DEFAULT_MODELS = 300 }; enum{ @@ -442,6 +370,15 @@ IsGlass(int16 id) inline bool IsTrafficLight(int16 id) +{ + return id == MI_TRAFFICLIGHTS || + id == MI_TRAFFICLIGHTS_VERTICAL || + id == MI_TRAFFICLIGHTS_MIAMI || + id == MI_TRAFFICLIGHTS_TWOVERTICAL; +} + +inline bool +IsLightWithoutShift(int16 id) { return id == MI_TRAFFICLIGHTS || id == MI_SINGLESTREETLIGHTS1 || @@ -450,89 +387,73 @@ IsTrafficLight(int16 id) id == MI_DOUBLESTREETLIGHTS; } +inline bool +IsLightWithPreRenderEffects(int16 id) +{ + return IsTrafficLight(id) || + id == MI_SINGLESTREETLIGHTS1 || + id == MI_SINGLESTREETLIGHTS2 || + id == MI_SINGLESTREETLIGHTS3 || + id == MI_DOUBLESTREETLIGHTS; +} + +inline bool +IsLightThatNeedsRepositioning(int16 id) +{ + return id == MI_SINGLESTREETLIGHTS1 || + id == MI_SINGLESTREETLIGHTS2 || + id == MI_SINGLESTREETLIGHTS3 || + id == MI_TRAFFICLIGHTS_MIAMI || + id == MI_TRAFFICLIGHTS_TWOVERTICAL || + id == MI_MLAMPPOST || + id == MI_STREETLAMP1 || + id == MI_STREETLAMP2; +} + +inline bool +IsLightObject(int16 id) +{ + return id == MI_TRAFFICLIGHTS_MIAMI || + id == MI_MLAMPPOST || + id == MI_SINGLESTREETLIGHTS1 || + id == MI_SINGLESTREETLIGHTS2 || + id == MI_SINGLESTREETLIGHTS3 || + id == MI_DOUBLESTREETLIGHTS || + id == MI_TRAFFICLIGHTS_TWOVERTICAL; +} + inline bool IsBodyPart(int16 id) { return id == MI_BODYPARTA || id == MI_BODYPARTB; } -// This is bad and should perhaps not be used -/* -inline bool -IsBoatModel(int16 id) -{ - return id == MI_PREDATOR || - id == MI_REEFER || - id == MI_SPEEDER || - id == MI_GHOST; -} -*/ - inline bool IsPedModel(int16 id) { - return id >= 0 && id <= 89; + return id >= MI_PLAYER && id <= MI_LAST_PED; +} +inline bool +IsPalmTreeModel(int16 id) +{ + return id == MI_VEG_PALM01 || + id == MI_VEG_PALM02 || + id == MI_VEG_PALM03 || + id == MI_VEG_PALM04 || + id == MI_VEG_PALM05 || + id == MI_VEG_PALM06 || + id == MI_VEG_PALM07 || + id == MI_VEG_PALM08; } inline bool IsTreeModel(int16 id) { - return id == MI_TREE1 || - id == MI_TREE2 || + return id == MI_TREE2 || id == MI_TREE3 || - id == MI_TREE4 || - id == MI_TREE5 || id == MI_TREE6 || - id == MI_TREE7 || id == MI_TREE8 || - id == MI_TREE9 || - id == MI_TREE10 || - id == MI_TREE11 || - id == MI_TREE12 || - id == MI_TREE13 || - id == MI_TREE14; -} - -inline bool -IsBannerModel(int16 id) -{ - return id == MI_CHINABANNER1 || - id == MI_CHINABANNER2 || - id == MI_CHINABANNER3 || - id == MI_CHINABANNER4 || - id == MI_CHINABANNER5 || - id == MI_CHINABANNER6 || - id == MI_CHINABANNER7 || - id == MI_CHINABANNER8 || - id == MI_CHINABANNER9 || - id == MI_CHINABANNER10 || - id == MI_CHINABANNER11 || - id == MI_CHINABANNER12 || - id == MI_ITALYBANNER1 || - id == MI_CHINALANTERN; -} -inline bool -IsPickupModel(int16 id) -{ - return id == MI_GRENADE || - id == MI_AK47 || - id == MI_BASEBALL_BAT || - id == MI_COLT || - id == MI_MOLOTOV || - id == MI_ROCKETLAUNCHER || - id == MI_SHOTGUN || - id == MI_SNIPER || - id == MI_UZI || - id == MI_M16 || - id == MI_FLAMETHROWER || - id == MI_PICKUP_ADRENALINE || - id == MI_PICKUP_BODYARMOUR || - id == MI_PICKUP_INFO || - id == MI_PICKUP_HEALTH || - id == MI_PICKUP_BONUS || - id == MI_PICKUP_BRIBE || - id == MI_PICKUP_KILLFRENZY || - id == MI_PICKUP_CAMERA; + IsPalmTreeModel(id); } inline bool @@ -557,7 +478,8 @@ inline bool IsExplosiveThingModel(int16 id) { return id == MI_EXPLODINGBARREL || - id == MI_PETROLPUMP; + id == MI_PETROLPUMP || + id == MI_PETROLPUMP2; } inline bool diff --git a/src/modelinfo/PedModelInfo.cpp b/src/modelinfo/PedModelInfo.cpp index bf81bd8a..a9caa867 100644 --- a/src/modelinfo/PedModelInfo.cpp +++ b/src/modelinfo/PedModelInfo.cpp @@ -96,7 +96,7 @@ CPedModelInfo::CreateHitColModelSkinned(RpClump *clump) center.x = pos.x + m_pColNodeInfos[i].x; center.y = pos.y + 0.0f; center.z = pos.z + m_pColNodeInfos[i].z; - spheres[i].Set(m_pColNodeInfos[i].radius, center, SURFACE_FLESH, m_pColNodeInfos[i].pieceType); + spheres[i].Set(m_pColNodeInfos[i].radius, center, SURFACE_PED, m_pColNodeInfos[i].pieceType); } RwMatrixDestroy(invmat); RwMatrixDestroy(mat); diff --git a/src/objects/Object.cpp b/src/objects/Object.cpp index a5896975..daa48d98 100644 --- a/src/objects/Object.cpp +++ b/src/objects/Object.cpp @@ -11,9 +11,11 @@ #include "ObjectData.h" #include "World.h" #include "Floater.h" +#include "soundlist.h" int16 CObject::nNoTempObjects; -int16 CObject::nBodyCastHealth = 1000; +//int16 CObject::nBodyCastHealth = 1000; +float CObject::fDistToNearestTree; void *CObject::operator new(size_t sz) { return CPools::GetObjectPool()->New(); } void *CObject::operator new(size_t sz, int handle) { return CPools::GetObjectPool()->New(handle);}; @@ -160,6 +162,7 @@ CObject::ObjectDamage(float amount) return; static int8 nFrameGen = 0; bool bBodyCastDamageEffect = false; +#if 0 if (GetModelIndex() == MI_BODYCAST) { if (amount > 50.0f) nBodyCastHealth = (int16)(nBodyCastHealth - 0.5f * amount); @@ -169,6 +172,7 @@ CObject::ObjectDamage(float amount) bBodyCastDamageEffect = true; amount = 0.0f; } +#endif if ((amount * m_fCollisionDamageMultiplier > 150.0f || bBodyCastDamageEffect) && m_nCollisionDamageEffect) { const CVector& vecPos = m_matrix.GetPosition(); const float fDirectionZ = 0.0002f * amount; @@ -220,7 +224,7 @@ CObject::ObjectDamage(float amount) int32 nRotationSpeed = CGeneral::GetRandomNumberInRange(-40, 80); CParticle::AddParticle(PARTICLE_CAR_DEBRIS, vecPos, vecDir, nil, fSize, randomColor, nRotationSpeed, 0, currentFrame, 0); } - PlayOneShotScriptObject(_SCRSOUND_CARDBOARD_BOX_SMASH, vecPos); + PlayOneShotScriptObject(SCRIPT_SOUND_BOX_DESTROYED_2, vecPos); break; } case DAMAGE_EFFECT_SMASH_WOODENBOX_COMPLETELY: { @@ -243,7 +247,7 @@ CObject::ObjectDamage(float amount) int32 nRotationSpeed = CGeneral::GetRandomNumberInRange(-40, 80); CParticle::AddParticle(PARTICLE_CAR_DEBRIS, vecPos, vecDir, nil, fSize, randomColor, nRotationSpeed, 0, currentFrame, 0); } - PlayOneShotScriptObject(_SCRSOUND_WOODEN_BOX_SMASH, vecPos); + PlayOneShotScriptObject(SCRIPT_SOUND_BOX_DESTROYED_1, vecPos); break; } case DAMAGE_EFFECT_SMASH_TRAFFICCONE_COMPLETELY: { @@ -268,7 +272,7 @@ CObject::ObjectDamage(float amount) int32 nRotationSpeed = CGeneral::GetRandomNumberInRange(-40, 80); CParticle::AddParticle(PARTICLE_CAR_DEBRIS, vecPos, vecDir, nil, fSize, color, nRotationSpeed, 0, currentFrame, 0); } - PlayOneShotScriptObject(_SCRSOUND_TYRE_BUMP, vecPos); + PlayOneShotScriptObject(SCRIPT_SOUND_TIRE_COLLISION, vecPos); break; } case DAMAGE_EFFECT_SMASH_BARPOST_COMPLETELY: { @@ -293,7 +297,7 @@ CObject::ObjectDamage(float amount) int32 nRotationSpeed = CGeneral::GetRandomNumberInRange(-40, 80); CParticle::AddParticle(PARTICLE_CAR_DEBRIS, vecPos, vecDir, nil, fSize, color, nRotationSpeed, 0, currentFrame, 0); } - PlayOneShotScriptObject(_SCRSOUND_COL_CAR, vecPos); + PlayOneShotScriptObject(SCRIPT_SOUND_METAL_COLLISION, vecPos); break; } } @@ -326,6 +330,8 @@ CObject::Init(void) m_colour1 = 0; m_colour2 = 0; m_nBonusValue = 0; + bIsWeapon = false; +// TODO(MIAMI): some new field here m_pCollidingEntity = nil; CColPoint point; CEntity* outEntity = nil; @@ -334,10 +340,15 @@ CObject::Init(void) m_pCurSurface = outEntity; else m_pCurSurface = nil; - if (GetModelIndex() == MI_BODYCAST) - nBodyCastHealth = 1000; - else if (GetModelIndex() == MI_BUOY) + + if (GetModelIndex() == MI_BUOY) bTouchingWater = true; + + if(CModelInfo::GetModelInfo(GetModelIndex())->GetModelType() == MITYPE_WEAPON) + bIsWeapon = true; + bIsStreetLight = IsLightObject(GetModelIndex()); + + m_area = AREA_EVERYWHERE; } bool @@ -395,3 +406,18 @@ CObject::DeleteAllTempObjectsInArea(CVector point, float fRadius) } } } + +bool +IsObjectPointerValid(CObject* pObject) +{ + if (!pObject) + return false; + int index = CPools::GetObjectPool()->GetJustIndex(pObject); +#ifdef FIX_BUGS + if (index < 0 || index >= CPools::GetObjectPool()->GetSize()) +#else + if (index < 0 || index > CPools::GetObjectPool()->GetSize()) +#endif + return false; + return pObject->bIsBIGBuilding || pObject->m_entryInfoList.first; +} diff --git a/src/objects/Object.h b/src/objects/Object.h index 20c99b1b..5a9c0195 100644 --- a/src/objects/Object.h +++ b/src/objects/Object.h @@ -59,26 +59,23 @@ public: CMatrix m_objectMatrix; float m_fUprootLimit; int8 ObjectCreatedBy; - int8 bIsPickup : 1; - int8 bPickupObjWithMessage : 1; - int8 bOutOfStock : 1; - int8 bGlassCracked : 1; - int8 bGlassBroken : 1; - int8 bHasBeenDamaged : 1; - int8 bUseVehicleColours : 1; + uint8 bIsPickup : 1; + uint8 obj_flag_02 : 1; + uint8 bPickupObjWithMessage : 1; + uint8 bOutOfStock : 1; + uint8 bGlassCracked : 1; + uint8 bGlassBroken : 1; + uint8 bHasBeenDamaged : 1; + uint8 bUseVehicleColours : 1; + uint8 bIsWeapon : 1; + uint8 bIsStreetLight : 1; int8 m_nBonusValue; float m_fCollisionDamageMultiplier; uint8 m_nCollisionDamageEffect; uint8 m_nSpecialCollisionResponseCases; bool m_bCameraToAvoidThisObject; - - // this batch is unused - int8 field_17B; - int8 field_17C; - int8 field_17D; - int8 field_17E; - int8 field_17F; - + int8 m_nBeachballBounces; + uint32 m_obj_unused1; uint32 m_nEndOfLifeTime; int16 m_nRefModelIndex; CEntity *m_pCurSurface; @@ -86,7 +83,7 @@ public: int8 m_colour1, m_colour2; static int16 nNoTempObjects; - static int16 nBodyCastHealth; + static float fDistToNearestTree; static void *operator new(size_t); static void *operator new(size_t, int); @@ -113,3 +110,5 @@ public: static void DeleteAllTempObjects(); static void DeleteAllTempObjectsInArea(CVector point, float fRadius); }; + +bool IsObjectPointerValid(CObject* pObject); diff --git a/src/peds/CivilianPed.cpp b/src/peds/CivilianPed.cpp index 1d6782fc..dd438a3f 100644 --- a/src/peds/CivilianPed.cpp +++ b/src/peds/CivilianPed.cpp @@ -9,6 +9,9 @@ #include "World.h" #include "Vehicle.h" #include "SurfaceTable.h" +#include "Weather.h" +#include "PedAttractor.h" +#include "Object.h" CCivilianPed::CCivilianPed(ePedType pedtype, uint32 mi) : CPed(pedtype) { @@ -16,6 +19,8 @@ CCivilianPed::CCivilianPed(ePedType pedtype, uint32 mi) : CPed(pedtype) for (int i = 0; i < ARRAY_SIZE(m_nearPeds); i++) { m_nearPeds[i] = nil; } + m_nAttractorCycleState = 0; + m_bAttractorUnk = (CGeneral::GetRandomNumberInRange(0.0f, 1.0f) < 1.25f); } void @@ -98,7 +103,7 @@ CCivilianPed::CivilianAI(void) SetLookTimer(500); } else if (closestThreatFlag == PED_FLAG_DEADPEDS) { float eventDistSqr = (m_pEventEntity->GetPosition() - GetPosition()).MagnitudeSqr2D(); - if (IsGangMember() && m_nPedType == ((CPed*)m_pEventEntity)->m_nPedType) { + if (((CPed*)m_pEventEntity)->bIsDrowning || IsGangMember() && m_nPedType == ((CPed*)m_pEventEntity)->m_nPedType) { if (eventDistSqr < sq(5.0f)) { SetFindPathAndFlee(m_pEventEntity, 2000); SetMoveState(PEDMOVE_RUN); @@ -195,7 +200,7 @@ CCivilianPed::ProcessControl(void) if (DyingOrDead()) return; - GetWeapon()->Update(m_audioEntityId); + GetWeapon()->Update(m_audioEntityId, nil); switch (m_nPedState) { case PED_WANDER_RANGE: case PED_WANDER_PATH: @@ -212,7 +217,7 @@ CCivilianPed::ProcessControl(void) // fall through case PED_SEEK_POS: if (Seek()) { - if ((m_objective == OBJECTIVE_GOTO_AREA_ON_FOOT || m_objective == OBJECTIVE_RUN_TO_AREA) && m_pNextPathNode) { + if ((m_objective == OBJECTIVE_GOTO_AREA_ON_FOOT || m_objective == OBJECTIVE_RUN_TO_AREA || IsUseAttractorObjective(m_objective)) && m_pNextPathNode) { m_pNextPathNode = nil; #ifdef TOGGLEABLE_BETA_FEATURES } else if (bRunningToPhone && m_objective < OBJECTIVE_FLEE_TILL_SAFE) { @@ -244,7 +249,7 @@ CCivilianPed::ProcessControl(void) } else if (m_objective == OBJECTIVE_GOTO_CHAR_ON_FOOT && m_pedInObjective && m_pedInObjective->m_nMoveState != PEDMOVE_STILL) { SetMoveState(m_pedInObjective->m_nMoveState); - } else if (m_objective == OBJECTIVE_GOTO_AREA_ON_FOOT || m_objective == OBJECTIVE_RUN_TO_AREA) { + } else if (m_objective == OBJECTIVE_GOTO_AREA_ON_FOOT || m_objective == OBJECTIVE_RUN_TO_AREA || IsUseAttractorObjective(m_objective)) { SetIdle(); } else { RestorePreviousState(); @@ -320,7 +325,7 @@ CCivilianPed::ProcessControl(void) CWorld::Players[CWorld::PlayerInFocus].m_nSexFrequency = Max(250, playerSexFrequency - 10); } - m_pMyVehicle->pDriver->m_fHealth = Min(125.0f, 1.0f + m_pMyVehicle->pDriver->m_fHealth); + m_pMyVehicle->pDriver->m_fHealth = Min(CWorld::Players[0].m_nMaxHealth + 25.0f, 1.0f + m_pMyVehicle->pDriver->m_fHealth); if (CWorld::Players[CWorld::PlayerInFocus].m_nSexFrequency == 250) CWorld::Players[CWorld::PlayerInFocus].m_nNextSexFrequencyUpdateTime = CTimer::GetTimeInMilliseconds() + 3000; } else { @@ -331,7 +336,7 @@ CCivilianPed::ProcessControl(void) } else { bWanderPathAfterExitingCar = true; CWorld::Players[CWorld::PlayerInFocus].m_pHooker = nil; - m_pMyVehicle->pDriver->m_fHealth = 125.0f; + m_pMyVehicle->pDriver->m_fHealth = CWorld::Players[0].m_nMaxHealth + 25.0f; SetObjective(OBJECTIVE_LEAVE_VEHICLE, m_pMyVehicle); } } else { @@ -365,6 +370,10 @@ CCivilianPed::ProcessControl(void) if (IsPedInControl()) CivilianAI(); + if (CharCreatedBy == RANDOM_CHAR) { + UseNearbyAttractors(); + } + if (CTimer::GetTimeInMilliseconds() > m_timerUnused) { m_stateUnused = 0; m_timerUnused = 0; @@ -373,3 +382,90 @@ CCivilianPed::ProcessControl(void) if (m_moved.Magnitude() > 0.0f) Avoid(); } + +const int32 gFrequencyOfAttractorAttempt = 11; +const float gDistanceToSeekAttractors = 50.0f; +const float gMaxDistanceToAttract = 10.0f; + +/* Probably this was inlined */ +void CCivilianPed::FindNearbyAttractorsSectorList(CPtrList& list, float& minDistance, C2dEffect*& pClosestAttractor, CEntity*& pAttractorEntity) +{ + for (CPtrNode* pNode = list.first; pNode != nil; pNode = pNode->next) { + CEntity* pEntity = (CEntity*)pNode->item; + if (pEntity->IsObject() && (!pEntity->IsStatic() || ((CObject*)pEntity)->bHasBeenDamaged)) + continue; + CBaseModelInfo* pModelInfo = CModelInfo::GetModelInfo(pEntity->GetModelIndex()); + for (int i = 0; i < pModelInfo->GetNum2dEffects(); i++) { + C2dEffect* pEffect = pModelInfo->Get2dEffect(i); + if (pEffect->type != EFFECT_PED_ATTRACTOR) + continue; + if (!IsAttractedTo(pEffect->pedattr.type)) + continue; + CVector pos; + CPedAttractorManager::ComputeEffectPos(pEffect, pEntity->GetMatrix(), pos); + if ((pos - GetPosition()).MagnitudeSqr() < minDistance) { + CPedAttractorManager* pManager = GetPedAttractorManager(); + if (pManager->HasEmptySlot(pEffect) && pManager->IsApproachable(pEffect, pEntity->GetMatrix(), 0, this)) { + pClosestAttractor = pEffect; + pAttractorEntity = pEntity; + minDistance = (pos - GetPosition()).MagnitudeSqr(); + } + } + } + } +} + +void CCivilianPed::UseNearbyAttractors() +{ + if (CWeather::Rain < 0.2f && !m_bAttractorUnk) + return; + if (HasAttractor()) + return; + if (m_nAttractorCycleState != gFrequencyOfAttractorAttempt) { + m_nAttractorCycleState++; + return; + } + m_nAttractorCycleState = 0; + if (!IsPedInControl()) + return; + if (m_nPedState == PED_FLEE_ENTITY) + return; + + float left = GetPosition().x - gDistanceToSeekAttractors; + float right = GetPosition().x + gDistanceToSeekAttractors; + float top = GetPosition().y - gDistanceToSeekAttractors; + float bottom = GetPosition().y + gDistanceToSeekAttractors; + int xstart = Max(0, CWorld::GetSectorIndexX(left)); + int xend = Min(NUMSECTORS_X - 1, CWorld::GetSectorIndexX(right)); + int ystart = Max(0, CWorld::GetSectorIndexY(top)); + int yend = Min(NUMSECTORS_Y - 1, CWorld::GetSectorIndexY(bottom)); + assert(xstart <= xend); + assert(ystart <= yend); + + float minDistance = SQR(gMaxDistanceToAttract); + C2dEffect* pClosestAttractor = nil; + CEntity* pAttractorEntity = nil; + + for (int y = ystart; y <= yend; y++) { + for (int x = xstart; x <= xend; x++) { + CSector* s = CWorld::GetSector(x, y); + FindNearbyAttractorsSectorList(s->m_lists[ENTITYLIST_BUILDINGS], minDistance, pClosestAttractor, pAttractorEntity); + FindNearbyAttractorsSectorList(s->m_lists[ENTITYLIST_OBJECTS], minDistance, pClosestAttractor, pAttractorEntity); + } + } + if (pClosestAttractor) + GetPedAttractorManager()->RegisterPedWithAttractor(this, pClosestAttractor, pAttractorEntity->GetMatrix()); +} + +bool CCivilianPed::IsAttractedTo(int8 type) +{ + switch (type) { + case ATTRACTOR_ATM: return true; + case ATTRACTOR_SEAT: return true; + case ATTRACTOR_STOP: return true; + case ATTRACTOR_PIZZA: return true; + case ATTRACTOR_SHELTER: return CWeather::Rain >= 0.2f; + case ATTRACTOR_ICECREAM: return false; + } + return false; +} diff --git a/src/peds/CivilianPed.h b/src/peds/CivilianPed.h index 8418a99f..27d458f7 100644 --- a/src/peds/CivilianPed.h +++ b/src/peds/CivilianPed.h @@ -4,12 +4,17 @@ class CCivilianPed : public CPed { + bool m_bAttractorUnk; + int32 m_nAttractorCycleState; public: CCivilianPed(ePedType, uint32); ~CCivilianPed(void) { } void CivilianAI(void); void ProcessControl(void); + void UseNearbyAttractors(void); + void FindNearbyAttractorsSectorList(CPtrList&, float&, C2dEffect*&, CEntity*&); + bool IsAttractedTo(int8); }; #ifndef PED_SKIN VALIDATE_SIZE(CCivilianPed, 0x53C); diff --git a/src/peds/CopPed.cpp b/src/peds/CopPed.cpp index 1affb64d..6fb858f6 100644 --- a/src/peds/CopPed.cpp +++ b/src/peds/CopPed.cpp @@ -23,7 +23,7 @@ CCopPed::CCopPed(eCopType copType, int32 modifier) : CPed(PEDTYPE_COP) switch (copType) { case COP_STREET: SetModelIndex(MI_COP); - // GiveWeapon(WEAPONTYPE_NIGHTSTICK, 1000, true); // TODO(Miami) + GiveWeapon(WEAPONTYPE_NIGHTSTICK, 1000, true); GiveDelayedWeapon(WEAPONTYPE_COLT45, 1000); m_currentWeapon = WEAPONTYPE_UNARMED; m_fArmour = 0.0f; @@ -257,7 +257,7 @@ CCopPed::ArrestPlayer(void) CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_ARREST_GUN, 4.0f); CVector suspMidPos; - suspect->m_pedIK.GetComponentPosition((RwV3d*)suspMidPos, PED_MID); + suspect->m_pedIK.GetComponentPosition(*(RwV3d *)&suspMidPos, PED_MID); m_fRotationDest = CGeneral::GetRadianAngleBetweenPoints(suspMidPos.x, suspMidPos.y, GetPosition().x, GetPosition().y); @@ -589,7 +589,7 @@ CCopPed::ProcessControl(void) ArrestPlayer(); return; } - GetWeapon()->Update(m_audioEntityId); + GetWeapon()->Update(m_audioEntityId, nil); if (m_moved.Magnitude() > 0.0f) Avoid(); diff --git a/src/peds/EmergencyPed.cpp b/src/peds/EmergencyPed.cpp index 04e5dd6a..1988366d 100644 --- a/src/peds/EmergencyPed.cpp +++ b/src/peds/EmergencyPed.cpp @@ -49,7 +49,7 @@ CEmergencyPed::ProcessControl(void) return; if(!DyingOrDead()) { - GetWeapon()->Update(m_audioEntityId); + GetWeapon()->Update(m_audioEntityId, nil); if (IsPedInControl() && m_moved.Magnitude() > 0.0f) Avoid(); @@ -231,8 +231,8 @@ CEmergencyPed::MedicAI(void) if (nearestAccident) { m_pRevivedPed = nearestAccident->m_pVictim; m_pRevivedPed->RegisterReference((CEntity**)&m_pRevivedPed); - m_pRevivedPed->m_pedIK.GetComponentPosition((RwV3d*)&midPos, PED_MID); - m_pRevivedPed->m_pedIK.GetComponentPosition((RwV3d*)&headPos, PED_HEAD); + m_pRevivedPed->m_pedIK.GetComponentPosition(*(RwV3d *)&midPos, PED_MID); + m_pRevivedPed->m_pedIK.GetComponentPosition(*(RwV3d *)&headPos, PED_HEAD); SetSeek((headPos + midPos) * 0.5f, 1.0f); SetObjective(OBJECTIVE_NONE); bIsRunning = true; @@ -271,8 +271,8 @@ CEmergencyPed::MedicAI(void) m_nEmergencyPedState = EMERGENCY_PED_STOP; break; } - m_pRevivedPed->m_pedIK.GetComponentPosition((RwV3d*)&midPos, PED_MID); - m_pRevivedPed->m_pedIK.GetComponentPosition((RwV3d*)&headPos, PED_HEAD); + m_pRevivedPed->m_pedIK.GetComponentPosition(*(RwV3d *)&midPos, PED_MID); + m_pRevivedPed->m_pedIK.GetComponentPosition(*(RwV3d *)&headPos, PED_HEAD); SetSeek((headPos + midPos) * 0.5f, nearestAccident->m_nMedicsPerformingCPR * 0.5f + 1.0f); SetObjective(OBJECTIVE_NONE); bIsRunning = true; @@ -326,8 +326,8 @@ CEmergencyPed::MedicAI(void) if (!m_pRevivedPed || m_pRevivedPed->m_fHealth > 0.0f) m_nEmergencyPedState = EMERGENCY_PED_DETERMINE_NEXT_STATE; else { - m_pRevivedPed->m_pedIK.GetComponentPosition((RwV3d*)&midPos, PED_MID); - m_pRevivedPed->m_pedIK.GetComponentPosition((RwV3d*)&headPos, PED_HEAD); + m_pRevivedPed->m_pedIK.GetComponentPosition(*(RwV3d *)&midPos, PED_MID); + m_pRevivedPed->m_pedIK.GetComponentPosition(*(RwV3d *)&headPos, PED_HEAD); midPos = (headPos + midPos) * 0.5f; m_fRotationDest = CGeneral::GetRadianAngleBetweenPoints( midPos.x, midPos.y, @@ -348,8 +348,8 @@ CEmergencyPed::MedicAI(void) m_nEmergencyPedState = EMERGENCY_PED_DETERMINE_NEXT_STATE; break; } - m_pRevivedPed->m_pedIK.GetComponentPosition((RwV3d*)&midPos, PED_MID); - m_pRevivedPed->m_pedIK.GetComponentPosition((RwV3d*)&headPos, PED_HEAD); + m_pRevivedPed->m_pedIK.GetComponentPosition(*(RwV3d *)&midPos, PED_MID); + m_pRevivedPed->m_pedIK.GetComponentPosition(*(RwV3d *)&headPos, PED_HEAD); midPos = (headPos + midPos) * 0.5f; m_fRotationDest = CGeneral::GetRadianAngleBetweenPoints( midPos.x, midPos.y, diff --git a/src/peds/Gangs.cpp b/src/peds/Gangs.cpp index 2a075e52..2d6d1137 100644 --- a/src/peds/Gangs.cpp +++ b/src/peds/Gangs.cpp @@ -2,12 +2,17 @@ #include "ModelIndices.h" #include "Gangs.h" +#include "General.h" +#include "Streaming.h" #include "Weapon.h" CGangInfo CGangs::Gang[NUM_GANGS]; +bool CGangs::GangAttackWithCops[NUM_GANGS]; CGangInfo::CGangInfo() : - m_nVehicleMI(MI_BUS), + m_nVehicleMI(-1), + m_nPedModel1MI(-1), + m_nPedModel2MI(-1), m_nPedModelOverride(-1), m_Weapon1(WEAPONTYPE_UNARMED), m_Weapon2(WEAPONTYPE_UNARMED) @@ -15,21 +20,63 @@ CGangInfo::CGangInfo() : void CGangs::Initialise(void) { - Gang[GANG_MAFIA].m_nVehicleMI = -1; - Gang[GANG_TRIAD].m_nVehicleMI = -1; - Gang[GANG_DIABLOS].m_nVehicleMI = -1; - Gang[GANG_YAKUZA].m_nVehicleMI = -1; - Gang[GANG_YARDIE].m_nVehicleMI = -1; - Gang[GANG_COLUMB].m_nVehicleMI = -1; - Gang[GANG_HOODS].m_nVehicleMI = -1; - Gang[GANG_7].m_nVehicleMI = -1; - Gang[GANG_8].m_nVehicleMI = -1; + SetGangPedModels(GANG_CUBAN, MI_CBA, MI_CBB); + SetGangPedModels(GANG_HAITIAN, MI_HNA, MI_HNB); + SetGangPedModels(GANG_STREET, MI_SGA, MI_SGB); + SetGangPedModels(GANG_DIAZ, MI_CLA, MI_CLB); + SetGangPedModels(GANG_SECURITY, MI_GDA, MI_GDB); + SetGangPedModels(GANG_BIKER, MI_BKA, MI_BKB); + SetGangPedModels(GANG_PLAYER, MI_PGA, MI_PGB); + SetGangPedModels(GANG_GOLFER, MI_WFOGO, MI_WMOGO); + SetGangVehicleModel(GANG_CUBAN, MI_CUBAN); + SetGangVehicleModel(GANG_HAITIAN, MI_VOODOO); + SetGangVehicleModel(GANG_STREET, MI_GANGBUR); + SetGangVehicleModel(GANG_DIAZ, -1); + SetGangVehicleModel(GANG_SECURITY, -1); + SetGangVehicleModel(GANG_BIKER, MI_ANGEL); + SetGangVehicleModel(GANG_PLAYER, -1); + SetGangVehicleModel(GANG_GOLFER, MI_CADDY); + SetGangWeapons(GANG_GOLFER, WEAPONTYPE_GOLFCLUB, WEAPONTYPE_GOLFCLUB); #ifdef FIX_BUGS for (int i = 0; i < NUM_GANGS; i++) - Gang[i].m_nPedModelOverride = -1; + SetGangPedModelOverride(i, -1); #endif } +bool CGangs::HaveGangModelsLoaded(int16 gang) +{ + CGangInfo* pGangInfo = GetGangInfo(gang); + return CStreaming::HasModelLoaded(pGangInfo->m_nPedModel1MI) && CStreaming::HasModelLoaded(pGangInfo->m_nPedModel2MI); +} + +void CGangs::SetGangPedModels(int16 gang, int32 mi1, int32 mi2) +{ + GetGangInfo(gang)->m_nPedModel1MI = mi1; + GetGangInfo(gang)->m_nPedModel2MI = mi2; +} + +void CGangs::SetWillAttackPlayerWithCops(ePedType type, bool will) +{ + if (type >= PEDTYPE_GANG1 && type <= PEDTYPE_GANG9) + GangAttackWithCops[type - PEDTYPE_GANG1] = will; +} + +bool CGangs::GetWillAttackPlayerWithCops(ePedType type) +{ + if (type >= PEDTYPE_GANG1 && type <= PEDTYPE_GANG9) + return GangAttackWithCops[type - PEDTYPE_GANG1]; + return false; +} + +int32 CGangs::ChooseGangPedModel(int16 gang) +{ + CGangInfo* pGangInfo = GetGangInfo(gang); + if (pGangInfo->m_nPedModelOverride != -1 || CGeneral::GetRandomTrueFalse()) + return pGangInfo->m_nPedModel1MI; + else + return pGangInfo->m_nPedModel2MI; +} + void CGangs::SetGangVehicleModel(int16 gang, int32 model) { GetGangInfo(gang)->m_nVehicleMI = model; diff --git a/src/peds/Gangs.h b/src/peds/Gangs.h index c8ea2916..c6381343 100644 --- a/src/peds/Gangs.h +++ b/src/peds/Gangs.h @@ -1,8 +1,12 @@ #pragma once +#include "PedType.h" + struct CGangInfo { int32 m_nVehicleMI; + int32 m_nPedModel1MI; + int32 m_nPedModel2MI; int8 m_nPedModelOverride; int32 m_Weapon1; int32 m_Weapon2; @@ -13,15 +17,15 @@ struct CGangInfo VALIDATE_SIZE(CGangInfo, 0x10); enum { - GANG_MAFIA = 0, - GANG_TRIAD, - GANG_DIABLOS, - GANG_YAKUZA, - GANG_YARDIE, - GANG_COLUMB, - GANG_HOODS, - GANG_7, - GANG_8, + GANG_CUBAN = 0, + GANG_HAITIAN, + GANG_STREET, + GANG_DIAZ, + GANG_SECURITY, + GANG_BIKER, + GANG_PLAYER, + GANG_GOLFER, + GANG_9, NUM_GANGS }; @@ -36,9 +40,18 @@ public: static void SaveAllGangData(uint8 *, uint32 *); static void LoadAllGangData(uint8 *, uint32); + static void SetGangPedModels(int16, int32, int32); + static void SetWillAttackPlayerWithCops(ePedType type, bool will); + static bool GetWillAttackPlayerWithCops(ePedType type); + static int32 ChooseGangPedModel(int16); + + static bool HaveGangModelsLoaded(int16 gang); + static int32 GetGangPedModel1(int16 gang) { return Gang[gang].m_nPedModel1MI; } + static int32 GetGangPedModel2(int16 gang) { return Gang[gang].m_nPedModel2MI; } static int32 GetGangVehicleModel(int16 gang) { return Gang[gang].m_nVehicleMI; } static CGangInfo *GetGangInfo(int16 gang) { return &Gang[gang]; } private: static CGangInfo Gang[NUM_GANGS]; + static bool GangAttackWithCops[NUM_GANGS]; }; diff --git a/src/peds/Ped.cpp b/src/peds/Ped.cpp index ee54ea60..691b5195 100644 --- a/src/peds/Ped.cpp +++ b/src/peds/Ped.cpp @@ -58,13 +58,18 @@ #include "ParticleObject.h" #include "Floater.h" #include "Streaming.h" +#include "PedAttractor.h" +#include "Debug.h" #define CAN_SEE_ENTITY_ANGLE_THRESHOLD DEGTORAD(60.0f) CPed *gapTempPedList[50]; uint16 gnNumTempPedList; -CColPoint aTempPedColPts[MAX_COLLISION_POINTS]; +static CColPoint aTempPedColPts[MAX_COLLISION_POINTS]; + +// TODO(Miami) +#define AUDIO_NOT_READY // Corresponds to ped sounds (from SOUND_PED_DEATH to SOUND_PED_TAXI_CALL) PedAudioData CommentWaitTime[39] = { @@ -112,32 +117,8 @@ uint16 nPlayerInComboMove; RpClump *flyingClumpTemp; -// This is beta fistfite.dat array. Not used anymore since they're being fetched from fistfite.dat. FightMove tFightMoves[NUM_FIGHTMOVES] = { - {NUM_ANIMS, 0.0f, 0.0f, 0.0f, 0.0f, HITLEVEL_NULL, 0, 0}, - {ANIM_PUNCH_R, 0.2f, 8.0f / 30.0f, 0.0f, 0.3f, HITLEVEL_HIGH, 1, 0}, - {ANIM_FIGHT_IDLE, 0.0f, 0.0f, 0.0f, 0.0f, HITLEVEL_NULL, 0, 0}, - {ANIM_FIGHT_SH_F, 0.0f, 0.0f, 0.0f, 0.0f, HITLEVEL_NULL, 0, 0}, - {ANIM_FIGHT_KNEE, 4.0f / 30.0f, 0.2f, 0.0f, 0.6f, HITLEVEL_LOW, 2, 0}, - {ANIM_FIGHT_HEAD, 4.0f / 30.0f, 0.2f, 0.0f, 0.7f, HITLEVEL_HIGH, 3, 0}, - {ANIM_FIGHT_PUNCH, 4.0f / 30.0f, 7.0f / 30.0f, 10.0f / 30.0f, 0.4f, HITLEVEL_HIGH, 1, 0}, - {ANIM_FIGHT_LHOOK, 8.0f / 30.0f, 10.0f / 30.0f, 0.0f, 0.4f, HITLEVEL_HIGH, 3, 0}, - {ANIM_FIGHT_KICK, 8.0f / 30.0f, 10.0f / 30.0f, 0.0f, 0.5, HITLEVEL_MEDIUM, 2, 0}, - {ANIM_FIGHT_LONGKICK, 8.0f / 30.0f, 10.0f / 30.0f, 0.0f, 0.5, HITLEVEL_MEDIUM, 4, 0}, - {ANIM_FIGHT_ROUNDHOUSE, 8.0f / 30.0f, 10.0f / 30.0f, 0.0f, 0.6f, HITLEVEL_MEDIUM, 4, 0}, - {ANIM_FIGHT_BODYBLOW, 5.0f / 30.0f, 7.0f / 30.0f, 0.0f, 0.35f, HITLEVEL_LOW, 2, 0}, - {ANIM_KICK_FLOOR, 10.0f / 30.0f, 14.0f / 30.0f, 0.0f, 0.4f, HITLEVEL_GROUND, 1, 0}, - {ANIM_HIT_FRONT, 0.0f, 0.0f, 0.0f, 0.0f, HITLEVEL_NULL, 0, 0}, - {ANIM_HIT_BACK, 0.0f, 0.0f, 0.0f, 0.0f, HITLEVEL_NULL, 0, 0}, - {ANIM_HIT_RIGHT, 0.0f, 0.0f, 0.0f, 0.0f, HITLEVEL_NULL, 0, 0}, - {ANIM_HIT_LEFT, 0.0f, 0.0f, 0.0f, 0.0f, HITLEVEL_NULL, 0, 0}, - {ANIM_HIT_BODYBLOW, 0.0f, 0.0f, 0.0f, 0.0f, HITLEVEL_NULL, 0, 0}, - {ANIM_HIT_CHEST, 0.0f, 0.0f, 0.0f, 0.0f, HITLEVEL_NULL, 0, 0}, - {ANIM_HIT_HEAD, 0.0f, 0.0f, 0.0f, 0.0f, HITLEVEL_NULL, 0, 0}, - {ANIM_HIT_WALK, 0.0f, 0.0f, 0.0f, 0.0f, HITLEVEL_NULL, 0, 0}, - {ANIM_FLOOR_HIT, 0.0f, 0.0f, 0.0f, 0.0f, HITLEVEL_NULL, 0, 0}, - {ANIM_HIT_BEHIND, 0.0f, 0.0f, 0.0f, 0.0f, HITLEVEL_NULL, 0, 0}, - {ANIM_FIGHT2_IDLE, 0.0f, 0.0f, 0.0f, 0.0f, HITLEVEL_NULL, 0, 0}, + // TODO(Miami) }; uint16 CPed::nThreatReactionRangeMultiplier = 1; @@ -385,6 +366,8 @@ CPed::DebugRenderOnePedText(void) CPed::~CPed(void) { CWorld::Remove(this); + if (m_attractor) + GetPedAttractorManager()->DeRegisterPed(this, m_attractor); CRadar::ClearBlipForEntity(BLIP_CHAR, CPools::GetPedPool()->GetIndex(this)); if (InVehicle()){ uint8 door_flag = GetCarDoorFlag(m_vehEnterType); @@ -403,6 +386,8 @@ CPed::~CPed(void) } if (m_pFire) m_pFire->Extinguish(); + + ClearWeapons(); if (bCarPassenger) CPopulation::ms_nTotalCarPassengerPeds--; if (bMiamiViceCop) @@ -426,10 +411,11 @@ CPed::FlagToDestroyWhenNextProcessed(void) } bInVehicle = false; m_pMyVehicle = nil; + if (CharCreatedBy == MISSION_CHAR) - m_nPedState = PED_DEAD; + SetPedState(PED_DEAD); else - m_nPedState = PED_NONE; + SetPedState(PED_NONE); m_pVehicleAnim = nil; } @@ -446,20 +432,24 @@ CPed::CPed(uint32 pedType) : m_pedIK(this) m_nPedType = pedType; m_lastSoundStart = 0; m_soundStart = 0; - m_lastQueuedSound = SOUND_TOTAL_PED_SOUNDS; - m_queuedSound = SOUND_TOTAL_PED_SOUNDS; + m_lastQueuedSound = SOUND_NO_SOUND; + m_queuedSound = SOUND_NO_SOUND; m_objective = OBJECTIVE_NONE; m_prevObjective = OBJECTIVE_NONE; CharCreatedBy = RANDOM_CHAR; m_leader = nil; m_pedInObjective = nil; + m_attractorHeading = 0.0f; m_carInObjective = nil; + m_attractorHeading = 0.0f; bInVehicle = false; m_pMyVehicle = nil; m_pVehicleAnim = nil; m_vecOffsetSeek.x = 0.0f; m_vecOffsetSeek.y = 0.0f; m_vecOffsetSeek.z = 0.0f; + m_attractor = nil; + m_positionInQueue = -1; m_pedFormation = FORMATION_UNDEFINED; m_collidingThingTimer = 0; m_nPedStateTimer = 0; @@ -488,6 +478,7 @@ CPed::CPed(uint32 pedType) : m_pedIK(this) m_vecSeekPos = CVector(0.0f, 0.0f, 0.0f); m_wepSkills = 0; m_distanceToCountSeekDone = 1.0f; + m_acceptableHeadingOffset = 0.1f; bRunningToPhone = false; m_phoneId = -1; m_lastAccident = 0; @@ -526,6 +517,8 @@ CPed::CPed(uint32 pedType) : m_pedIK(this) m_fAirResistance = 0.4f / m_fMass; m_fElasticity = 0.05f; + m_ceaseAttackTimer = 0; + bIsStanding = false; bWasStanding = false; bIsAttacking = false; @@ -606,13 +599,33 @@ CPed::CPed(uint32 pedType) : m_pedIK(this) #ifdef KANGAROO_CHEAT m_ped_flagI80 = false; #endif -#ifdef VC_PED_PORTS - bSomeVCflag1 = false; -#endif + m_gangFlags = 0xFF; + + bReachedAttractorHeadingTarget = false; + bTurnedAroundOnAttractor = false; bCarPassenger = false; bMiamiViceCop = false; + bMoneyHasBeenGivenByScript = false; + bHasBeenPhotographed = false; + + bIsDrowning = false; + bDrownsInWater = true; +#ifdef VC_PED_PORTS + bHeadStuckInCollision = false; +#endif + bIsPlayerFriend = true; bDeadPedInFrontOfCar = false; + bStayInCarOnJack = false; + + bDontFight = false; + bDoomAim = true; + bCanBeShotInVehicle = true; + bIgnoreThreatsBehindObjects = false; + + bNeverEverTargetThisPed = false; + + bBoughtIceCream = false; if ((CGeneral::GetRandomNumber() & 3) == 0) bHasACamera = true; @@ -635,6 +648,7 @@ CPed::CPed(uint32 pedType) : m_pedIK(this) m_maxWeaponTypeAllowed = WEAPONTYPE_UNARMED; m_currentWeapon = WEAPONTYPE_UNARMED; m_storedWeapon = WEAPONTYPE_UNIDENTIFIED; + m_delayedWeapon = WEAPONTYPE_UNIDENTIFIED; for(int i = 0; i < TOTAL_WEAPON_SLOTS; i++) { CWeapon &weapon = GetWeapon(i); @@ -646,12 +660,21 @@ CPed::CPed(uint32 pedType) : m_pedIK(this) } m_lastFightMove = FIGHTMOVE_NULL; - GiveWeapon(WEAPONTYPE_UNARMED, 0); + GiveWeapon(WEAPONTYPE_UNARMED, 0, true); m_wepAccuracy = 60; m_lastWepDam = -1; + m_lastDamEntity = nil; + m_attachedTo = nil; + m_attachWepAmmo = 0; m_collPoly.valid = false; m_fCollisionSpeed = 0.0f; m_wepModelID = -1; + uint16 random = CGeneral::GetRandomNumber(); + m_nPedMoney = random % 25; + if (m_nPedMoney == 23) + m_nPedMoney = 400; + m_nExtendedRangeTimer = 0; + m_bleedCounter = 0; #ifdef PED_SKIN m_pWeaponModel = nil; #endif @@ -666,10 +689,10 @@ CPed::GiveWeapon(eWeaponType weaponType, uint32 ammo, bool unused) if (m_weapons[slot].m_eWeaponType == weaponType) { GetWeapon(slot).m_nAmmoTotal += ammo; - if (weaponType < WEAPONTYPE_LAST_WEAPONTYPE && weaponType > WEAPONTYPE_UNARMED && CWeaponInfo::ms_aMaxAmmoForWeapon[weaponType] >= 0) { + if (weaponType < WEAPONTYPE_TOTALWEAPONS && weaponType > WEAPONTYPE_UNARMED && CWeaponInfo::ms_aMaxAmmoForWeapon[weaponType] >= 0) { // Looks like abandoned idea. This block never runs, ms_aMaxAmmoForWeapon is always -1. - GetWeapon(slot).m_nAmmoTotal = Min(CWeaponInfo::ms_aMaxAmmoForWeapon[weaponType], (int32) GetWeapon(slot).m_nAmmoTotal); + GetWeapon(slot).m_nAmmoTotal = Min(CWeaponInfo::ms_aMaxAmmoForWeapon[weaponType], GetWeapon(slot).m_nAmmoTotal); } else { GetWeapon(slot).m_nAmmoTotal = Min(99999, GetWeapon(slot).m_nAmmoTotal); } @@ -865,9 +888,8 @@ CPed::AddWeaponModel(int id) CModelInfo::GetModelInfo(id)->AddRef(); m_wepModelID = id; - // TODO(Miami) - // if (IsPlayer() && id == MI_MINIGUN) - // ((CPlayerPed*)this)->m_pMinigunTopAtomic = (RpAtomic*)CModelInfo::GetModelInfo(MI_MINIGUN2)->CreateInstance(); + if (IsPlayer() && id == MI_MINIGUN) + ((CPlayerPed*)this)->m_pMinigunTopAtomic = (RpAtomic*)CModelInfo::GetModelInfo(MI_MINIGUN2)->CreateInstance(); } } @@ -879,7 +901,7 @@ CPed::AimGun(void) if (m_pSeekTarget) { if (m_pSeekTarget->IsPed()) { - ((CPed*)m_pSeekTarget)->m_pedIK.GetComponentPosition(&pos, PED_MID); + ((CPed*)m_pSeekTarget)->m_pedIK.GetComponentPosition(pos, PED_MID); vector = pos; } else { vector = m_pSeekTarget->GetPosition(); @@ -1166,10 +1188,10 @@ CPed::FinishedReloadCB(CAnimBlendAssociation *reloadAssoc, void *arg) if (ped->bIsDucking && ped->bCrouchWhenShooting) { CAnimBlendAssociation *crouchFireAssoc = nil; if (!!weapon->m_bCrouchFire) { - crouchFireAssoc = RpAnimBlendClumpGetAssociation(ped->GetClump(), ANIM_WEAPON_CROUCHFIRE); + crouchFireAssoc = RpAnimBlendClumpGetAssociation(ped->GetClump(), GetCrouchFireAnim(weapon)); } if (!!weapon->m_bReload && reloadAssoc) { - if (reloadAssoc->animId == ANIM_WEAPON_CROUCHRELOAD && !crouchFireAssoc) { + if (reloadAssoc->animId == GetCrouchReloadAnim(weapon) && !crouchFireAssoc) { CAnimBlendAssociation *crouchAssoc = CAnimManager::BlendAnimation(ped->GetClump(), ASSOCGRP_STD, ANIM_WEAPON_CROUCH, 8.0f); crouchAssoc->SetCurrentTime(crouchAssoc->hierarchy->totalLength); crouchAssoc->flags &= ~ASSOC_RUNNING; @@ -1177,7 +1199,7 @@ CPed::FinishedReloadCB(CAnimBlendAssociation *reloadAssoc, void *arg) } } else if (weapon->m_bReloadLoop2Start && ped->bIsAttacking) { CAnimBlendAssociation *fireAssoc = - CAnimManager::BlendAnimation(ped->GetClump(), weapon->m_AnimToPlay, weapon->m_bAnimDetonate ? ANIM_BOMBER : ANIM_WEAPON_FIRE, 8.0f); + CAnimManager::BlendAnimation(ped->GetClump(), weapon->m_AnimToPlay, GetPrimaryFireAnim(weapon), 8.0f); fireAssoc->SetFinishCallback(FinishedAttackCB, ped); fireAssoc->SetRun(); if (fireAssoc->currentTime != reloadAssoc->hierarchy->totalLength) { @@ -1202,10 +1224,10 @@ CPed::FinishedAttackCB(CAnimBlendAssociation *attackAssoc, void *arg) if (ped->m_nPedState != PED_ATTACK) { if (ped->bIsDucking && ped->IsPedInControl()) { if (currentWeapon->m_bReload) { - reloadAnimAssoc = RpAnimBlendClumpGetAssociation(ped->GetClump(), ANIM_WEAPON_CROUCHRELOAD); + reloadAnimAssoc = RpAnimBlendClumpGetAssociation(ped->GetClump(), GetCrouchReloadAnim(currentWeapon)); } if (currentWeapon->m_bCrouchFire && attackAssoc) { - if (attackAssoc->animId == ANIM_WEAPON_CROUCHFIRE && !reloadAnimAssoc) { + if (attackAssoc->animId == GetCrouchFireAnim(currentWeapon) && !reloadAnimAssoc) { newAnim = CAnimManager::BlendAnimation(ped->GetClump(), ASSOCGRP_STD, ANIM_WEAPON_CROUCH, 8.0f); newAnim->SetCurrentTime(newAnim->hierarchy->totalLength); newAnim->flags &= ~ASSOC_RUNNING; @@ -1228,10 +1250,10 @@ CPed::FinishedAttackCB(CAnimBlendAssociation *attackAssoc, void *arg) if (ped->bIsDucking && ped->bCrouchWhenShooting) { if (currentWeapon->m_bReload) { - reloadAnimAssoc = RpAnimBlendClumpGetAssociation(ped->GetClump(), ANIM_WEAPON_CROUCHRELOAD); + reloadAnimAssoc = RpAnimBlendClumpGetAssociation(ped->GetClump(), GetCrouchReloadAnim(currentWeapon)); } if (currentWeapon->m_bCrouchFire && attackAssoc) { - if (attackAssoc->animId == ANIM_WEAPON_CROUCHFIRE && !reloadAnimAssoc) { + if (attackAssoc->animId == GetCrouchFireAnim(currentWeapon) && !reloadAnimAssoc) { newAnim = CAnimManager::BlendAnimation(ped->GetClump(), ASSOCGRP_STD, ANIM_WEAPON_CROUCH, 8.0f); newAnim->SetCurrentTime(newAnim->hierarchy->totalLength); newAnim->flags &= ~ASSOC_RUNNING; @@ -1259,15 +1281,6 @@ CPed::FinishedAttackCB(CAnimBlendAssociation *attackAssoc, void *arg) newAnim->SetFinishCallback(FinishedAttackCB, ped); } } else { - // TODO(Miami): Remove this block when fighting has been ported - if (attackAssoc && attackAssoc->animId == ANIM_FIGHT_PPUNCH && currentWeapon->m_AnimToPlay == ASSOCGRP_STD) - { - attackAssoc->blendDelta = -8.0f; - attackAssoc->flags |= ASSOC_DELETEFADEDOUT; - ped->ClearAttack(); - return; - } - if (attackAssoc && attackAssoc->animId == ANIM_MELEE_ATTACK && currentWeapon->m_AnimToPlay == ASSOCGRP_UNARMED) { attackAssoc->blendDelta = -8.0f; @@ -1292,6 +1305,7 @@ CPed::FinishedAttackCB(CAnimBlendAssociation *attackAssoc, void *arg) } } +// --MIAMI: Done except commented things void CPed::Attack(void) { @@ -1303,7 +1317,6 @@ CPed::Attack(void) float animLoopEnd; CWeaponInfo *ourWeapon; bool attackShouldContinue; - AnimationId reloadAnim; CAnimBlendAssociation *reloadAnimAssoc; CAnimBlendAssociation *throwAssoc; float delayBetweenAnimAndFire; @@ -1317,7 +1330,6 @@ CPed::Attack(void) attackShouldContinue = bIsAttacking; reloadAnimAssoc = nil; throwAssoc = nil; - reloadAnim = NUM_ANIMS; animLoopStart = ourWeapon->m_fAnimLoopStart; animLoopEnd = ourWeapon->m_fAnimLoopEnd; delayBetweenAnimAndFire = ourWeapon->m_fAnimFrameFire; @@ -1325,7 +1337,7 @@ CPed::Attack(void) if (bIsDucking) { if (!!ourWeapon->m_bCrouchFire && bCrouchWhenShooting) { - weaponAnimAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_WEAPON_CROUCHFIRE); + weaponAnimAssoc = RpAnimBlendClumpGetAssociation(GetClump(), GetCrouchFireAnim(ourWeapon)); if (weaponAnimAssoc) { animLoopStart = ourWeapon->m_fAnim2LoopStart; animLoopEnd = ourWeapon->m_fAnim2LoopEnd; @@ -1343,11 +1355,11 @@ CPed::Attack(void) } if (ourWeapon->m_bReload) { - reloadAnimAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_WEAPON_RELOAD); + reloadAnimAssoc = RpAnimBlendClumpGetAssociation(GetClump(), GetReloadAnim(ourWeapon)); } if (!!ourWeapon->m_bReload && !reloadAnimAssoc) { - reloadAnimAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_WEAPON_CROUCHRELOAD); + reloadAnimAssoc = RpAnimBlendClumpGetAssociation(GetClump(), GetCrouchReloadAnim(ourWeapon)); } if ( reloadAnimAssoc && reloadAnimAssoc->IsRunning() ) { @@ -1378,7 +1390,6 @@ CPed::Attack(void) meleeAttackStarted = true; switch ( ourWeapon->m_AnimToPlay ) { - case ASSOCGRP_STD: // TODO(Miami): Remove that when weapons ported case ASSOCGRP_UNARMED: case ASSOCGRP_SCREWDRIVER: case ASSOCGRP_KNIFE: @@ -1419,7 +1430,7 @@ CPed::Attack(void) if (attackShouldContinue) { if (ourWeaponFire != WEAPON_FIRE_PROJECTILE || !IsPlayer() || ((CPlayerPed*)this)->m_bHaveTargetSelected) { if (bCrouchWhenShooting && bIsDucking && !!ourWeapon->m_bCrouchFire) { - weaponAnimAssoc = CAnimManager::BlendAnimation(GetClump(), ourWeapon->m_AnimToPlay, ANIM_WEAPON_CROUCHFIRE, 8.0f); + weaponAnimAssoc = CAnimManager::BlendAnimation(GetClump(), ourWeapon->m_AnimToPlay, GetCrouchFireAnim(ourWeapon), 8.0f); } else if(!!ourWeapon->m_bUse2nd && CGeneral::GetRandomNumber() & 1){ weaponAnimAssoc = CAnimManager::BlendAnimation(GetClump(), ourWeapon->m_AnimToPlay, ANIM_WEAPON_FIRE_2ND, 8.0f); @@ -1469,62 +1480,103 @@ CPed::Attack(void) m_pedIK.m_flags &= ~CPedIK::AIMS_WITH_ARM; } - // TODO(Miami): Chainsaw - if (weaponAnimTime <= delayBetweenAnimAndFire || weaponAnimTime - weaponAnimAssoc->timeStep > delayBetweenAnimAndFire || !weaponAnimAssoc->IsRunning()) { - if (weaponAnimAssoc->speed < 1.0f) - weaponAnimAssoc->speed = 1.0f; + if (ourWeaponType != WEAPONTYPE_CHAINSAW + || !meleeAttackStarted && delayBetweenAnimAndFire - 0.5f >= weaponAnimAssoc->currentTime + || weaponAnimAssoc->currentTime - weaponAnimAssoc->timeStep > delayBetweenAnimAndFire) { - } else { - firePos = ourWeapon->m_vecFireOffset; + if (ourWeaponType == WEAPONTYPE_CHAINSAW) { +#ifndef AUDIO_NOT_READY + DMAudio.PlayOneShot(m_audioEntityId, 52, 0.0f); +#endif + } else if (weaponAnimTime <= delayBetweenAnimAndFire || weaponAnimTime - weaponAnimAssoc->timeStep > delayBetweenAnimAndFire || !weaponAnimAssoc->IsRunning()) { + if (weaponAnimAssoc->speed < 1.0f) + weaponAnimAssoc->speed = 1.0f; - // TODO(Miami): Katana & Chainsaw - if (ourWeapon->m_eWeaponFire == WEAPON_FIRE_MELEE) { - firePos = GetMatrix() * firePos; } else { - // TODO(Miami): Remove ANIM_KICK_FLOOR when fighting is done - TransformToNode(firePos, (weaponAnimAssoc->animId == ANIM_KICK_FLOOR || - weaponAnimAssoc->animId == ANIM_MELEE_ATTACK_2ND && ourWeapon->m_AnimToPlay == ASSOCGRP_UNARMED) ? PED_FOOTR : PED_HANDR); - } + firePos = ourWeapon->m_vecFireOffset; + + if (ourWeaponType != WEAPONTYPE_KATANA && ourWeaponType != WEAPONTYPE_CHAINSAW) { + if (ourWeapon->m_eWeaponFire != WEAPON_FIRE_MELEE) { + TransformToNode(firePos, (weaponAnimAssoc->animId == ANIM_MELEE_ATTACK_2ND && ourWeapon->m_AnimToPlay == ASSOCGRP_UNARMED) ? PED_FOOTR : PED_HANDR); + } else { + firePos = GetMatrix() * firePos; + } + } else { + if (weaponAnimAssoc->animId == ANIM_MELEE_ATTACK_2ND) + firePos.z = 0.7f * ourWeapon->m_fRadius - 1.0f; + + firePos = GetMatrix() * firePos; + } + GetWeapon()->Fire(this, &firePos); + + if (ourWeaponType == WEAPONTYPE_MOLOTOV || ourWeaponType == WEAPONTYPE_GRENADE || ourWeaponType == WEAPONTYPE_DETONATOR_GRENADE || + ourWeaponType == WEAPONTYPE_TEARGAS) { + RemoveWeaponModel(ourWeapon->m_nModelId); + } + if (!GetWeapon()->m_nAmmoTotal && ourWeaponFire != WEAPON_FIRE_MELEE && FindPlayerPed() != this) { + SelectGunIfArmed(); + } + + if (GetWeapon()->m_eWeaponState == WEAPONSTATE_MELEE_MADECONTACT) { + int damagerType = ENTITY_TYPE_NOTHING; + if (m_pDamageEntity && (m_fDamageImpulse == 0.0f || !m_pDamageEntity->IsBuilding())) { + damagerType = m_pDamageEntity->GetType(); + } + switch (ourWeapon->m_AnimToPlay) { + case ASSOCGRP_UNARMED: + if (weaponAnimAssoc->animId == ANIM_MELEE_ATTACK || weaponAnimAssoc->animId == ANIM_MELEE_ATTACK_START) { +#ifdef AUDIO_NOT_READY + DMAudio.PlayOneShot(m_audioEntityId, SOUND_FIGHT_PUNCH_39, 0.0f); +#else + DMAudio.PlayOneShot(m_audioEntityId, SOUND_FIGHT_PUNCH_39, (damagerType | (ourWeaponType << 8))); +#endif + } + break; + case ASSOCGRP_KNIFE: + case ASSOCGRP_BASEBALLBAT: + case ASSOCGRP_GOLFCLUB: + case ASSOCGRP_CHAINSAW: +#ifdef AUDIO_NOT_READY + DMAudio.PlayOneShot(m_audioEntityId, SOUND_WEAPON_BAT_ATTACK, 1.0f); +#else + DMAudio.PlayOneShot(m_audioEntityId, SOUND_WEAPON_BAT_ATTACK, (damagerType | (ourWeaponType << 8))); +#endif + break; + default: + break; + } + + if (bIsAttacking || CTimer::GetTimeInMilliseconds() < m_shootTimer) { + weaponAnimAssoc->callbackType = 0; + } + } + + attackShouldContinue = false; + } + } else { + CVector firePos = ourWeapon->m_vecFireOffset; + + if (weaponAnimAssoc->animId == 206) + firePos.z = 0.7f * ourWeapon->m_fRadius - 1.0f; + + firePos = GetMatrix() * firePos; GetWeapon()->Fire(this, &firePos); - - // TODO(Miami) - if (ourWeaponType == WEAPONTYPE_MOLOTOV || ourWeaponType == WEAPONTYPE_GRENADE || ourWeaponType == WEAPONTYPE_DETONATOR_GRENADE - /* ourWeaponType == WEAPONTYPE_TEARGAS*/) { - RemoveWeaponModel(ourWeapon->m_nModelId); - } - if (!GetWeapon()->m_nAmmoTotal && ourWeaponFire != WEAPON_FIRE_MELEE && FindPlayerPed() != this) { - SelectGunIfArmed(); - } - if (GetWeapon()->m_eWeaponState == WEAPONSTATE_MELEE_MADECONTACT) { - int damagerType = 0; - if (m_pDamageEntity && (m_fDamageImpulse == 0.0f || !m_pDamageEntity->IsBuilding())) { + int damagerType = ENTITY_TYPE_PED; + if (m_pDamageEntity) damagerType = m_pDamageEntity->GetType(); - } - switch (ourWeapon->m_AnimToPlay) { - case ASSOCGRP_STD: // TODO(Miami): Remove after fighting done - case ASSOCGRP_UNARMED: - if (weaponAnimAssoc->animId == ANIM_FIGHT_PPUNCH || // TODO(Miami): Remove after fighting done - weaponAnimAssoc->animId == ANIM_MELEE_ATTACK || weaponAnimAssoc->animId == ANIM_MELEE_ATTACK_START) { - DMAudio.PlayOneShot(m_audioEntityId, SOUND_FIGHT_PUNCH_39, (damagerType | (ourWeaponType << 8))); - } - break; - case ASSOCGRP_KNIFE: - case ASSOCGRP_BASEBALLBAT: - case ASSOCGRP_GOLFCLUB: - case ASSOCGRP_CHAINSAW: - DMAudio.PlayOneShot(m_audioEntityId, SOUND_WEAPON_BAT_ATTACK, (damagerType | (ourWeaponType << 8))); - break; - default: - break; - } - if (bIsAttacking || CTimer::GetTimeInMilliseconds() < m_shootTimer) { - weaponAnimAssoc->callbackType = 0; + DMAudio.PlayOneShot(m_audioEntityId, 54, (float)damagerType); + if (IsPlayer()) { + CPad::GetPad(0)->StartShake(240, 180); + } + } else { + DMAudio.PlayOneShot(m_audioEntityId, 53, 0.0f); + if (IsPlayer()) { + CPad::GetPad(0)->StartShake(240, 90); } } - attackShouldContinue = false; } @@ -1576,12 +1628,12 @@ CPed::Attack(void) if (bIsDucking) { newReloadAssoc = CAnimManager::BlendAnimation( GetClump(), ourWeapon->m_AnimToPlay, - ANIM_WEAPON_CROUCHRELOAD, + GetCrouchReloadAnim(ourWeapon), 8.0f); } else { newReloadAssoc = CAnimManager::BlendAnimation( GetClump(), ourWeapon->m_AnimToPlay, - ANIM_WEAPON_RELOAD, + GetReloadAnim(ourWeapon), 8.0f); } newReloadAssoc->SetFinishCallback(FinishedReloadCB, this); @@ -1591,19 +1643,38 @@ CPed::Attack(void) bIsAttacking = false; bIsPointingGunAt = false; m_shootTimer = CTimer::GetTimeInMilliseconds(); +#ifdef AUDIO_NOT_READY + switch (ourWeaponType) { + case WEAPONTYPE_UZI: + case WEAPONTYPE_TEC9: + case WEAPONTYPE_SILENCED_INGRAM: + case WEAPONTYPE_MP5: + DMAudio.PlayOneShot(m_audioEntityId, SOUND_WEAPON_UZI_BULLET_ECHO, 0.0f); + break; + case WEAPONTYPE_RUGER: + DMAudio.PlayOneShot(m_audioEntityId, SOUND_WEAPON_AK47_BULLET_ECHO, 0.0f); + break; + case WEAPONTYPE_M4: + DMAudio.PlayOneShot(m_audioEntityId, SOUND_WEAPON_M16_BULLET_ECHO, 0.0f); + break; + default: + break; + } +#else DMAudio.PlayOneShot(m_audioEntityId, SOUND_WEAPON_AK47_BULLET_ECHO, GetWeapon()->m_eWeaponType); +#endif return; } } if (weaponAnimTime - 2.0f * weaponAnimAssoc->timeStep <= animLoopEnd && (bIsAttacking || CTimer::GetTimeInMilliseconds() < m_shootTimer) && (GetWeapon()->m_eWeaponState != WEAPONSTATE_RELOADING - /* || GetWeapon()->m_nWeaponType == WEAPONTYPE_MINIGUN */)) { + || GetWeapon()->m_eWeaponType == WEAPONTYPE_MINIGUN)) { PedOnGroundState pedOnGroundState; if (ourWeapon->m_eWeaponFire == WEAPON_FIRE_MELEE && (CGame::nastyGame && ((pedOnGroundState = CheckForPedsOnGroundToAttack(this, nil)) > PED_IN_FRONT_OF_ATTACKER) - || GetWeapon()->m_eWeaponType == WEAPONTYPE_BASEBALLBAT && pedOnGroundState == NO_PED && bIsStanding && m_pCurSurface && m_pCurSurface->IsVehicle())) { + || ourWeaponType == WEAPONTYPE_BASEBALLBAT && pedOnGroundState == NO_PED && bIsStanding && m_pCurSurface && m_pCurSurface->IsVehicle())) { AnimationId fireAnim = GetFireAnimGround(ourWeapon, false); if (weaponAnimAssoc->animId == fireAnim) @@ -1636,10 +1707,28 @@ CPed::Attack(void) ClearAimFlag(); // Echoes of bullets, at the end of the attack. (Bug: doesn't play while reloading) - if (weaponAnimAssoc->currentTime - weaponAnimAssoc->timeStep < ourWeapon->m_fAnimLoopEnd) { + if (weaponAnimAssoc->currentTime - weaponAnimAssoc->timeStep < animLoopEnd) { - // What?! Weapon id as volume?? - DMAudio.PlayOneShot(m_audioEntityId, SOUND_WEAPON_AK47_BULLET_ECHO, GetWeapon()->m_eWeaponType); +#ifdef AUDIO_NOT_READY + switch (ourWeaponType) { + case WEAPONTYPE_UZI: + case WEAPONTYPE_TEC9: + case WEAPONTYPE_SILENCED_INGRAM: + case WEAPONTYPE_MP5: + DMAudio.PlayOneShot(m_audioEntityId, SOUND_WEAPON_UZI_BULLET_ECHO, 0.0f); + break; + case WEAPONTYPE_RUGER: + DMAudio.PlayOneShot(m_audioEntityId, SOUND_WEAPON_AK47_BULLET_ECHO, 0.0f); + break; + case WEAPONTYPE_M4: + DMAudio.PlayOneShot(m_audioEntityId, SOUND_WEAPON_M16_BULLET_ECHO, 0.0f); + break; + default: + break; + } +#else + DMAudio.PlayOneShot(m_audioEntityId, SOUND_WEAPON_AK47_BULLET_ECHO, ourWeaponType); +#endif } // Fun fact: removing this part leds to reloading flamethrower @@ -1677,8 +1766,7 @@ CPed::RemoveWeaponModel(int modelId) #endif RwFrameForAllObjects(m_pFrames[PED_HANDR]->frame,RemoveAllModelCB,nil); - // TODO(Miami): Minigun - if (IsPlayer() && (modelId == -1 /* || modelId == MI_MINIGUN)*/)) { + if (IsPlayer() && (modelId == -1 || modelId == MI_MINIGUN)) { RpAtomic* &atm = ((CPlayerPed*)this)->m_pMinigunTopAtomic; if (atm) { RwFrame *frm = RpAtomicGetFrame(atm); @@ -1720,15 +1808,19 @@ CPed::SetCurrentWeapon(int slot) } } -// --MIAMI: TODO when weapons got converted +// --MIAMI: Done // Only used while deciding which gun ped should switch to, if no ammo left. bool CPed::SelectGunIfArmed(void) { - for (int i = 0; i < m_maxWeaponTypeAllowed; i++) { + for (int i = 0; i < TOTAL_WEAPON_SLOTS; i++) { if (GetWeapon(i).m_nAmmoTotal > 0) { eWeaponType weaponType = GetWeapon(i).m_eWeaponType; - if (weaponType >= WEAPONTYPE_COLT45 && weaponType != WEAPONTYPE_M16 && weaponType <= WEAPONTYPE_FLAMETHROWER) { + + // First condition checks for Pistol, Python and Shotguns + if ((weaponType >= WEAPONTYPE_COLT45 && weaponType < WEAPONTYPE_TEC9) || + weaponType == WEAPONTYPE_UZI || weaponType == WEAPONTYPE_M4 || weaponType == WEAPONTYPE_MP5 || + weaponType == WEAPONTYPE_ROCKETLAUNCHER || weaponType == WEAPONTYPE_FLAMETHROWER || weaponType == WEAPONTYPE_SNIPERRIFLE) { SetCurrentWeapon(i); return true; } @@ -1738,39 +1830,54 @@ CPed::SelectGunIfArmed(void) return false; } +// --MIAMI: Done void CPed::Duck(void) { if (CTimer::GetTimeInMilliseconds() > m_duckTimer) ClearDuck(); + else if (bIsDucking && bCrouchWhenShooting) { + CWeaponInfo *weapon = CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType); + CAnimBlendAssociation *attackAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_WEAPON_CROUCH); + if (!attackAssoc) { + if(!!weapon->m_bCrouchFire) + attackAssoc = RpAnimBlendClumpGetAssociation(GetClump(), GetCrouchFireAnim(weapon)); + } + if (!attackAssoc) { + if(!!weapon->m_bReload) + attackAssoc = RpAnimBlendClumpGetAssociation(GetClump(), GetCrouchReloadAnim(weapon)); + } + if (!attackAssoc) { + bIsDucking = false; + } + } } +// --MIAMI: Done void -CPed::ClearDuck(void) +CPed::ClearDuck(bool clearTimer) { CAnimBlendAssociation *animAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_DUCK_DOWN); if (!animAssoc) { animAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_DUCK_LOW); - - if (!animAssoc) { - bIsDucking = false; - return; - } } - if (!bCrouchWhenShooting) - return; + if (!animAssoc) { + animAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_WEAPON_CROUCH); + } - if (m_nPedState != PED_ATTACK && m_nPedState != PED_AIM_GUN) - return; + if (animAssoc) { + animAssoc->flags |= ASSOC_DELETEFADEDOUT; + animAssoc->blendDelta = -4.0f; + } + bIsDucking = false; - animAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_RBLOCK_CSHOOT); - if (!animAssoc || animAssoc->blendDelta < 0.0f) { - CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_RBLOCK_CSHOOT, 4.0f); + if (clearTimer) { + m_duckTimer = 0; } } -// --MIAMI: Done except commented thing +// --MIAMI: Done void CPed::ClearPointGunAt(void) { @@ -1781,17 +1888,14 @@ CPed::ClearPointGunAt(void) ClearAimFlag(); bIsPointingGunAt = false; if (m_nPedState == PED_AIM_GUN || m_nPedState == PED_ATTACK) { - - if (m_nPedState == PED_FOLLOW_PATH) - ClearFollowPath(); - m_nPedState = PED_IDLE; + SetPedState(PED_IDLE); RestorePreviousState(); } weaponInfo = CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType); animAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_WEAPON_FIRE); if (!animAssoc || animAssoc->blendDelta < 0.0f) { if (!!weaponInfo->m_bCrouchFire) { - animAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_WEAPON_CROUCHFIRE); + animAssoc = RpAnimBlendClumpGetAssociation(GetClump(), GetCrouchFireAnim(weaponInfo)); } } if (animAssoc) { @@ -1855,7 +1959,7 @@ CPed::BeingDraggedFromCar(void) #ifdef VC_PED_PORTS if (m_objective == OBJECTIVE_LEAVE_CAR_AND_DIE) { if (m_pMyVehicle) { - m_pMyVehicle->ProcessOpenDoor(m_vehEnterType, NUM_ANIMS, m_pVehicleAnim->currentTime * 5.0f); + m_pMyVehicle->ProcessOpenDoor(m_vehEnterType, NUM_STD_ANIMS, m_pVehicleAnim->currentTime * 5.0f); } } #endif @@ -2122,7 +2226,7 @@ CPed::LineUpPedWithCar(PedLineUpPhase phase) case ANIM_VAN_GETIN: #ifdef VC_PED_PORTS multExtractedFromAnim = true; - zBlend = Max(m_pVehicleAnim->currentTime / m_pVehicleAnim->hierarchy->totalLength - 0.3f, 0.0f) / (1.0f - 0.3f); + zBlend = Max(m_pVehicleAnim->GetProgress() - 0.3f, 0.0f) / (1.0f - 0.3f); // fall through #endif case ANIM_CAR_QJACKED: @@ -2133,7 +2237,7 @@ CPed::LineUpPedWithCar(PedLineUpPhase phase) #ifdef VC_PED_PORTS if (!multExtractedFromAnim) { multExtractedFromAnim = true; - zBlend = Max(m_pVehicleAnim->currentTime / m_pVehicleAnim->hierarchy->totalLength - 0.5f, 0.0f) / (1.0f - 0.5f); + zBlend = Max(m_pVehicleAnim->GetProgress() - 0.5f, 0.0f) / (1.0f - 0.5f); } // fall through #endif @@ -2141,14 +2245,14 @@ CPed::LineUpPedWithCar(PedLineUpPhase phase) case ANIM_CAR_CRAWLOUT_RHS2: case ANIM_VAN_GETOUT_L: case ANIM_VAN_GETOUT: - seatPosMult = m_pVehicleAnim->currentTime / m_pVehicleAnim->hierarchy->totalLength; + seatPosMult = m_pVehicleAnim->GetProgress(); break; case ANIM_CAR_GETIN_RHS: case ANIM_CAR_GETIN_LHS: #ifdef VC_PED_PORTS if (veh && veh->IsCar() && veh->bIsBus) { multExtractedFromAnimBus = true; - zBlend = Min(m_pVehicleAnim->currentTime / m_pVehicleAnim->hierarchy->totalLength, 0.5f) / 0.5f; + zBlend = Min(m_pVehicleAnim->GetProgress(), 0.5f) / 0.5f; } // fall through #endif @@ -2309,7 +2413,7 @@ particleProduceFootDust(CPed *ped, CVector const &pos, float size, int times) switch (ped->m_nSurfaceTouched) { case SURFACE_TARMAC: - case SURFACE_DIRT: + case SURFACE_GRAVEL: case SURFACE_PAVEMENT: case SURFACE_SAND: for (int i = 0; i < times; ++i) { @@ -2462,7 +2566,7 @@ CPed::PlayFootSteps(void) } } - if (m_nSurfaceTouched == SURFACE_PUDDLE) { + if (m_nSurfaceTouched == SURFACE_WATER) { float pedSpeed = CVector2D(m_vecMoveSpeed).Magnitude(); if (pedSpeed > 0.03f && CTimer::GetFrameCounter() % 2 == 0 && pedSpeed > 0.13f) { #ifdef PC_PARTICLE @@ -2617,6 +2721,7 @@ CPed::SetPedStats(ePedStats pedStat) m_pedStats = CPedStats::ms_apPedStats[pedStat]; } +// --MIAMI: Done void CPed::SetModelIndex(uint32 mi) { @@ -2629,19 +2734,37 @@ CPed::SetModelIndex(uint32 mi) m_animGroup = (AssocGroupId) modelInfo->m_animGroup; CAnimManager::AddAnimation(GetClump(), m_animGroup, ANIM_IDLE_STANCE); + // TODO(Miami): This is inlined CanUseTorsoWhenLooking + bool canUseMyBody = false; + if (m_nPedState != PED_DRIVING && m_nPedState != PED_DRAG_FROM_CAR && !bIsDucking) { + if (m_animGroup != ASSOCGRP_SEXYWOMAN && m_animGroup != ASSOCGRP_WOMAN) + canUseMyBody = true; + } + if (!canUseMyBody) + m_pedIK.m_flags |= CPedIK::LOOKAROUND_HEAD_ONLY; + // This is a mistake by R*, velocity is CVector, whereas m_vecAnimMoveDelta is CVector2D. (*RPANIMBLENDCLUMPDATA(m_rwObject))->velocity = (CVector*) &m_vecAnimMoveDelta; #ifdef PED_SKIN if(modelInfo->GetHitColModel() == nil) modelInfo->CreateHitColModelSkinned(GetClump()); + + if (IsClumpSkinned(GetClump())) // condition isn't there in VC + UpdateRpHAnim(); #endif } void CPed::RemoveLighting(bool reset) { - CRenderer::RemoveVehiclePedLights(this, reset); + if (!bRenderScorched) { + CRenderer::RemoveVehiclePedLights(this, reset); + if (reset) + ReSetAmbientAndDirectionalColours(); + } + SetAmbientColours(); + DeActivateDirectional(); } bool @@ -2706,14 +2829,15 @@ CPed::WorkOutHeadingForMovingFirstPerson(float offset) angle = CGeneral::GetRadianAngleBetweenPoints(0.0f, 0.0f, -leftRight, upDown); } else { if (leftRight < 0.0f) - angle = 0.5f * PI; + angle = HALFPI; else if (leftRight > 0.0f) - angle = -0.5f * PI; + angle = -HALFPI; } return CGeneral::LimitRadianAngle(offset + angle); } +// --MIAMI: Done void CPed::CalculateNewVelocity(void) { @@ -2728,9 +2852,6 @@ CPed::CalculateNewVelocity(void) limitedRotDest -= 2 * PI; } - if (IsPlayer() && m_nPedState == PED_ATTACK) - headAmount /= 4.0f; - float neededTurn = limitedRotDest - m_fRotationCur; if (neededTurn <= headAmount) { if (neededTurn > (-headAmount)) @@ -2754,8 +2875,12 @@ CPed::CalculateNewVelocity(void) } if ((!TheCamera.Cams[TheCamera.ActiveCam].GetWeaponFirstPersonOn() && !TheCamera.Cams[0].Using3rdPersonMouseCam()) - || FindPlayerPed() != this || !CanStrafeOrMouseControl()) + || FindPlayerPed() != this || !CanStrafeOrMouseControl()) { + + if (FindPlayerPed() == this) + FindPlayerPed()->m_fWalkAngle = 0.0f; return; + } float walkAngle = WorkOutHeadingForMovingFirstPerson(m_fRotationCur); float pedSpeed = m_moved.Magnitude(); @@ -2775,16 +2900,13 @@ CPed::CalculateNewVelocity(void) CAnimBlendAssociation *idleAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_IDLE_STANCE); CAnimBlendAssociation *fightAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_FIGHT_IDLE); -#ifdef VC_PED_PORTS if(!fightAssoc) fightAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_IDLE_TIRED); - // There is one more anim in VC. + if(!fightAssoc) + fightAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_WEAPON_CROUCHRELOAD); if ((!idleAssoc || idleAssoc->blendAmount < 0.5f) && !fightAssoc && !bIsDucking) { -#else - if ((!idleAssoc || idleAssoc->blendAmount < 0.5f) && !fightAssoc) { -#endif LimbOrientation newUpperLegs; newUpperLegs.yaw = localWalkAngle; @@ -2843,7 +2965,7 @@ CPed::CanPedDriveOff(void) bool CPed::CanPedJumpThis(CEntity *unused, CVector *damageNormal = nil) { - if (m_nSurfaceTouched == SURFACE_PUDDLE) + if (m_nSurfaceTouched == SURFACE_WATER) return true; CVector pos = GetPosition(); @@ -3864,16 +3986,11 @@ CPed::ClearAttackByRemovingAnim(void) return; CWeaponInfo *weapon = CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType); - CAnimBlendAssociation *weaponAssoc = RpAnimBlendClumpGetAssociation(GetClump(), weapon->m_bAnimDetonate ? ANIM_BOMBER : ANIM_WEAPON_FIRE); - - // TODO(Miami): Remove when fighting got ported - if (!weaponAssoc) { - weaponAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_FIGHT_PPUNCH); - } + CAnimBlendAssociation *weaponAssoc = RpAnimBlendClumpGetAssociation(GetClump(), GetPrimaryFireAnim(weapon)); if (!weaponAssoc) { if (!!weapon->m_bCrouchFire) - weaponAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_WEAPON_CROUCHFIRE); + weaponAssoc = RpAnimBlendClumpGetAssociation(GetClump(), GetCrouchFireAnim(weapon)); } if (!weaponAssoc) { if(!!weapon->m_bFinish3rd) @@ -3927,6 +4044,8 @@ CPed::SetStoredState(void) void CPed::SetDie(AnimationId animId, float delta, float speed) { + if (m_attractor) + GetPedAttractorManager()->DeRegisterPed(this, m_attractor); CPlayerPed *player = FindPlayerPed(); if (player == this) { if (!player->m_bCanBeDamaged) @@ -3954,7 +4073,7 @@ CPed::SetDie(AnimationId animId, float delta, float speed) } m_nPedState = PED_DIE; - if (animId == NUM_ANIMS) { + if (animId == NUM_STD_ANIMS) { bIsPedDieAnimPlaying = false; } else { CAnimBlendAssociation *dieAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, animId, delta); @@ -3977,6 +4096,7 @@ CPed::SetDie(AnimationId animId, float delta, float speed) m_bloodyFootprintCountOrDeathTime = CTimer::GetTimeInMilliseconds(); } +// --MIAMI: Done except commented things bool CPed::InflictDamage(CEntity *damagedBy, eWeaponType method, float damage, ePedPieceTypes pedPiece, uint8 direction) { @@ -3988,17 +4108,28 @@ CPed::InflictDamage(CEntity *damagedBy, eWeaponType method, float damage, ePedPi bool willLinger = false; int random; + // TODO(Miami): PlayerInfo thingies here + if (player == this) { if (!player->m_bCanBeDamaged) return false; + if (damagedBy && damagedBy->IsPed() && ((CPed*)damagedBy)->m_nPedType == PEDTYPE_GANG7) + return false; + + if ((method == WEAPONTYPE_FLAMETHROWER || method == WEAPONTYPE_MOLOTOV) && CWorld::Players[CWorld::PlayerInFocus].m_bFireproof) + return false; + player->AnnoyPlayerPed(false); } if (DyingOrDead()) return false; - if (!bUsesCollision && method != WEAPONTYPE_DROWNING) + if (method == WEAPONTYPE_DROWNING && !bDrownsInWater) + return false; + + if (!bUsesCollision && (!bInVehicle || m_nPedState != PED_DRIVING) && method != WEAPONTYPE_DROWNING) return false; if (bOnlyDamagedByPlayer && damagedBy != player && damagedBy != FindPlayerVehicle() && @@ -4011,8 +4142,12 @@ CPed::InflictDamage(CEntity *damagedBy, eWeaponType method, float damage, ePedPi else healthImpact = damage * m_pedStats->m_defendWeakness; + if (!IsPlayer() && + (method == WEAPONTYPE_SCREWDRIVER || method == WEAPONTYPE_KNIFE || (method >= WEAPONTYPE_CLEAVER && method <= WEAPONTYPE_CHAINSAW))) + m_bleedCounter = 200; + bool detectDieAnim = true; - if (m_nPedState == PED_FALL || m_nPedState == PED_GETUP) { + if (m_nPedState == PED_GETUP) { if (!IsPedHeadAbovePos(-0.3f)) { if (RpAnimBlendClumpGetFirstAssociation(GetClump(), ASSOC_FRONTAL)) dieAnim = ANIM_FLOOR_HIT_F; @@ -4021,20 +4156,36 @@ CPed::InflictDamage(CEntity *damagedBy, eWeaponType method, float damage, ePedPi dieDelta *= 2.0f; dieSpeed = 0.5f; detectDieAnim = false; - } else if (m_nPedState == PED_FALL) { - dieAnim = NUM_ANIMS; - detectDieAnim = false; } + } else if (m_nPedState == PED_FALL) { + CAnimBlendAssociation *fallAssoc = RpAnimBlendClumpGetFirstAssociation(GetClump(), ASSOC_PARTIAL); + if (!fallAssoc || fallAssoc->IsRunning()) { + if (fallAssoc && fallAssoc->blendDelta >= 0.0f) + dieAnim = NUM_STD_ANIMS; + else + dieAnim = ANIM_KO_SHOT_FRONT1; + } else { + if (fallAssoc->flags & ASSOC_FRONTAL) + dieAnim = ANIM_FLOOR_HIT_F; + else + dieAnim = ANIM_FLOOR_HIT; + + dieDelta *= 2.0f; + dieSpeed = 0.5f; + } + detectDieAnim = false; } + if (detectDieAnim) { switch (method) { case WEAPONTYPE_UNARMED: + case WEAPONTYPE_BRASSKNUCKLE: if (bMeleeProof) return false; if (m_nPedState == PED_FALL) { if (IsPedHeadAbovePos(-0.3f)) { - dieAnim = NUM_ANIMS; + dieAnim = NUM_STD_ANIMS; } else { if (RpAnimBlendClumpGetFirstAssociation(GetClump(), ASSOC_FRONTAL)) dieAnim = ANIM_FLOOR_HIT_F; @@ -4062,19 +4213,28 @@ CPed::InflictDamage(CEntity *damagedBy, eWeaponType method, float damage, ePedPi } } break; + case WEAPONTYPE_SCREWDRIVER: + case WEAPONTYPE_GOLFCLUB: + case WEAPONTYPE_NIGHTSTICK: + case WEAPONTYPE_KNIFE: case WEAPONTYPE_BASEBALLBAT: + case WEAPONTYPE_HAMMER: + case WEAPONTYPE_CLEAVER: + case WEAPONTYPE_MACHETE: + case WEAPONTYPE_KATANA: + case WEAPONTYPE_CHAINSAW: if (bMeleeProof) return false; -#ifdef VC_PED_PORTS - if (/*method != WEAPONTYPE_KATANA || */ + + if (method != WEAPONTYPE_KATANA || damagedBy != FindPlayerPed() || FindPlayerPed()->m_nPedState != PED_FIGHT - /*|| FindPlayerPed()->m_lastFightMove != 28 && FindPlayerPed()->m_lastFightMove != 29 */ + || FindPlayerPed()->m_lastFightMove != FIGHTMOVE_MELEE1 && FindPlayerPed()->m_lastFightMove != FIGHTMOVE_MELEE2 || CGeneral::GetRandomNumber() & 3) { if (m_nPedState == PED_FALL) { if (IsPedHeadAbovePos(-0.3f)) { - dieAnim = NUM_ANIMS; + dieAnim = NUM_STD_ANIMS; } else { if (RpAnimBlendClumpGetFirstAssociation(GetClump(), ASSOC_FRONTAL)) dieAnim = ANIM_FLOOR_HIT_F; @@ -4083,8 +4243,8 @@ CPed::InflictDamage(CEntity *damagedBy, eWeaponType method, float damage, ePedPi dieDelta = dieDelta * 2.0f; dieSpeed = 0.5f; } - } else if (damagedBy != FindPlayerPed()) { // || FindPlayerPed()->m_lastFightMove != 29) - //if (damagedBy != FindPlayerPed() || FindPlayerPed()->m_lastFightMove != 30) { + } else if (damagedBy != FindPlayerPed() || FindPlayerPed()->m_lastFightMove != FIGHTMOVE_MELEE2) { + if (damagedBy != FindPlayerPed() || FindPlayerPed()->m_lastFightMove != FIGHTMOVE_MELEE3) { switch (direction) { case 0: dieAnim = ANIM_KO_SKID_FRONT; @@ -4101,82 +4261,49 @@ CPed::InflictDamage(CEntity *damagedBy, eWeaponType method, float damage, ePedPi default: break; } - //} else { - // dieAnim = ANIM_KO_SHOT_STOM; - //} + } else { + dieAnim = ANIM_KO_SHOT_STOM; + } } else { dieAnim = ANIM_KO_SHOT_FACE; } } else { dieAnim = ANIM_KO_SHOT_FACE; - // SpawnFlyingComponent in VC RemoveBodyPart(PED_HEAD, direction); headShot = true; willLinger = true; } -#else - if (m_nPedState == PED_FALL) { - if (IsPedHeadAbovePos(-0.3f)) { - dieAnim = NUM_ANIMS; - } else { - if (RpAnimBlendClumpGetFirstAssociation(GetClump(), ASSOC_FRONTAL)) - dieAnim = ANIM_FLOOR_HIT_F; - else - dieAnim = ANIM_FLOOR_HIT; - dieDelta = dieDelta * 2.0f; - dieSpeed = 0.5f; - } - } else { - switch (direction) { - case 0: - dieAnim = ANIM_KO_SKID_FRONT; - break; - case 1: - dieAnim = ANIM_KO_SPIN_R; - break; - case 2: - dieAnim = ANIM_KO_SKID_BACK; - break; - case 3: - dieAnim = ANIM_KO_SPIN_L; - break; - default: - break; - } - } -#endif break; case WEAPONTYPE_COLT45: - case WEAPONTYPE_UZI: + case WEAPONTYPE_SHOTGUN: + case WEAPONTYPE_STUBBY_SHOTGUN: + case WEAPONTYPE_SPAS12_SHOTGUN: case WEAPONTYPE_TEC9: + case WEAPONTYPE_UZI: case WEAPONTYPE_SILENCED_INGRAM: case WEAPONTYPE_MP5: - case WEAPONTYPE_SHOTGUN: - case WEAPONTYPE_AK47: - case WEAPONTYPE_M16: + case WEAPONTYPE_M4: + case WEAPONTYPE_RUGER: case WEAPONTYPE_SNIPERRIFLE: + case WEAPONTYPE_LASERSCOPE: + case WEAPONTYPE_M60: + case WEAPONTYPE_MINIGUN: + case WEAPONTYPE_UZI_DRIVEBY: + if (bBulletProof) return false; bool dontRemoveLimb; if (IsPlayer() || bNoCriticalHits) dontRemoveLimb = true; - else { - switch (method) { - case WEAPONTYPE_SNIPERRIFLE: - dontRemoveLimb = false; - break; - case WEAPONTYPE_M16: - dontRemoveLimb = false; - break; - case WEAPONTYPE_SHOTGUN: - dontRemoveLimb = CGeneral::GetRandomNumber() & 7; - break; - default: - dontRemoveLimb = CGeneral::GetRandomNumber() & 15; - break; - } - } + else if (method != WEAPONTYPE_M4 && method != WEAPONTYPE_RUGER && method != WEAPONTYPE_SNIPERRIFLE && + method != WEAPONTYPE_LASERSCOPE) { + if (method == WEAPONTYPE_SHOTGUN) + dontRemoveLimb = CGeneral::GetRandomNumber() & 7; + else + dontRemoveLimb = CGeneral::GetRandomNumber() & 15; + } else + dontRemoveLimb = false; if (dontRemoveLimb) { if (method == WEAPONTYPE_SHOTGUN) { @@ -4241,8 +4368,8 @@ CPed::InflictDamage(CEntity *damagedBy, eWeaponType method, float damage, ePedPi } } break; - case WEAPONTYPE_ROCKETLAUNCHER: case WEAPONTYPE_GRENADE: + case WEAPONTYPE_ROCKETLAUNCHER: case WEAPONTYPE_EXPLOSION: if (bExplosionProof) return false; @@ -4339,7 +4466,7 @@ CPed::InflictDamage(CEntity *damagedBy, eWeaponType method, float damage, ePedPi default: break; } - if (damagedBy) { + if (damagedBy && pedPiece != PEDPIECE_TORSO) { CVehicle *vehicle = (CVehicle*)damagedBy; if (method == WEAPONTYPE_RAMMEDBYCAR) { float vehSpeed = vehicle->m_vecMoveSpeed.Magnitude(); @@ -4398,6 +4525,16 @@ CPed::InflictDamage(CEntity *damagedBy, eWeaponType method, float damage, ePedPi CWorld::Players[CWorld::PlayerInFocus].m_nTimeLastHealthLoss = CTimer::GetTimeInMilliseconds(); m_lastWepDam = method; + m_lastDamEntity = damagedBy; + } + + if (method == WEAPONTYPE_FALL) { + if (RpAnimBlendClumpGetAssociation(GetClump(), ANIM_CAR_ROLLOUT_LHS)) { + if (m_fHealth >= 1.0 && m_fHealth - healthImpact < 5.0f) { + m_fHealth = Min(m_fHealth, 5.0f); + return false; + } + } } if (m_fHealth - healthImpact >= 1.0f && !willLinger) { @@ -4409,6 +4546,8 @@ CPed::InflictDamage(CEntity *damagedBy, eWeaponType method, float damage, ePedPi if (method != WEAPONTYPE_DROWNING) { #ifdef VC_PED_PORTS if (m_pMyVehicle) { + + // TODO(Miami): Bikes if (m_pMyVehicle->IsCar() && m_pMyVehicle->pDriver == this) { if (m_pMyVehicle->GetStatus() == STATUS_SIMPLE) { m_pMyVehicle->SetStatus(STATUS_PHYSICS); @@ -4419,7 +4558,8 @@ CPed::InflictDamage(CEntity *damagedBy, eWeaponType method, float damage, ePedPi m_pMyVehicle->AutoPilot.m_nTempAction = TEMPACT_HANDBRAKESTRAIGHT; m_pMyVehicle->AutoPilot.m_nTimeTempAction = CTimer::GetTimeInMilliseconds() + 2000; } - if (m_pMyVehicle->CanPedExitCar()) { +// TODO(MIAMI): argument + if (m_pMyVehicle->CanPedExitCar(false)) { SetObjective(OBJECTIVE_LEAVE_CAR_AND_DIE, m_pMyVehicle); } else { m_fHealth = 0.0f; @@ -4430,7 +4570,7 @@ CPed::InflictDamage(CEntity *damagedBy, eWeaponType method, float damage, ePedPi SetDie(dieAnim, dieDelta, dieSpeed); /* if (damagedBy == FindPlayerPed() && damagedBy != this) { - // PlayerInfo stuff + // TODO(Miami): PlayerInfo stuff } */ } @@ -4459,7 +4599,7 @@ CPed::InflictDamage(CEntity *damagedBy, eWeaponType method, float damage, ePedPi if (player == this) m_pMyVehicle->SetStatus(STATUS_PLAYER_DISABLED); - SetDie(NUM_ANIMS, 4.0f, 0.0f); + SetDie(NUM_STD_ANIMS, 4.0f, 0.0f); return true; } else { m_fHealth = 0.0f; @@ -4467,7 +4607,7 @@ CPed::InflictDamage(CEntity *damagedBy, eWeaponType method, float damage, ePedPi if (damagedBy == player || damagedBy && damagedBy == FindPlayerVehicle()) { - // There are PlayerInfo stuff here in VC + // TODO(Miami): PlayerInfo stuff CDarkel::RegisterKillByPlayer(this, method, headShot); m_threatEntity = player; } else { @@ -4512,7 +4652,7 @@ CPed::SetGetUp(void) } if (m_nPedState != PED_GETUP) { SetStoredState(); - m_nPedState = PED_GETUP; + SetPedState(PED_GETUP); } CVehicle *collidingVeh = (CVehicle*)m_pCollidingEntity; @@ -4555,7 +4695,7 @@ CPed::SetGetUp(void) animAssoc->SetFinishCallback(PedGetupCB,this); } else { m_fHealth = 0.0f; - SetDie(NUM_ANIMS, 4.0f, 0.0f); + SetDie(NUM_STD_ANIMS, 4.0f, 0.0f); } } @@ -4829,10 +4969,7 @@ CPed::SetPointGunAt(CEntity *to) if (m_nPedState != PED_ATTACK) SetStoredState(); - if (m_nPedState == PED_FOLLOW_PATH) - ClearFollowPath(); - - m_nPedState = PED_AIM_GUN; + SetPedState(PED_AIM_GUN); bIsPointingGunAt = true; SetMoveState(PEDMOVE_NONE); @@ -4840,7 +4977,7 @@ CPed::SetPointGunAt(CEntity *to) if (bCrouchWhenShooting && bIsDucking) { if (!!curWeapon->m_bCrouchFire) { - aimAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_WEAPON_CROUCHFIRE); + aimAssoc = RpAnimBlendClumpGetAssociation(GetClump(), GetCrouchFireAnim(curWeapon)); } } else { aimAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_WEAPON_FIRE); @@ -4849,7 +4986,7 @@ CPed::SetPointGunAt(CEntity *to) if (!aimAssoc || aimAssoc->blendDelta < 0.0f) { if (bCrouchWhenShooting && bIsDucking) { if (!!curWeapon->m_bCrouchFire) { - aimAssoc = CAnimManager::BlendAnimation(GetClump(), curWeapon->m_AnimToPlay, ANIM_WEAPON_CROUCHFIRE, 4.0f); + aimAssoc = CAnimManager::BlendAnimation(GetClump(), curWeapon->m_AnimToPlay, GetCrouchFireAnim(curWeapon), 4.0f); } } else { aimAssoc = CAnimManager::AddAnimation(GetClump(), curWeapon->m_AnimToPlay, ANIM_WEAPON_FIRE); @@ -4870,15 +5007,15 @@ CPed::SetAmmo(eWeaponType weaponType, uint32 ammo) if (slot == -1) return; - GetWeapon(slot).m_nAmmoTotal += ammo; - if (weaponType < WEAPONTYPE_LAST_WEAPONTYPE && weaponType > WEAPONTYPE_UNARMED && CWeaponInfo::ms_aMaxAmmoForWeapon[weaponType] >= 0) { + GetWeapon(slot).m_nAmmoTotal = ammo; + if (weaponType < WEAPONTYPE_TOTALWEAPONS && weaponType > WEAPONTYPE_UNARMED && CWeaponInfo::ms_aMaxAmmoForWeapon[weaponType] >= 0) { // Looks like abandoned idea. This block never runs, ms_aMaxAmmoForWeapon is always -1. - GetWeapon(slot).m_nAmmoTotal = Min(CWeaponInfo::ms_aMaxAmmoForWeapon[weaponType], (int32)GetWeapon(slot).m_nAmmoTotal); + GetWeapon(slot).m_nAmmoTotal = Min(CWeaponInfo::ms_aMaxAmmoForWeapon[weaponType], GetWeapon(slot).m_nAmmoTotal); } else { GetWeapon(slot).m_nAmmoTotal = Min(99999, GetWeapon(slot).m_nAmmoTotal); } - uint32 newClip = GetWeapon(slot).m_nAmmoTotal; + int32 newClip = GetWeapon(slot).m_nAmmoTotal; if (newClip >= GetWeapon(slot).m_nAmmoInClip) newClip = GetWeapon(slot).m_nAmmoInClip; GetWeapon(slot).m_nAmmoInClip = newClip; @@ -4896,10 +5033,10 @@ CPed::GrantAmmo(eWeaponType weaponType, uint32 ammo) return; GetWeapon(slot).m_nAmmoTotal += ammo; - if (weaponType < WEAPONTYPE_LAST_WEAPONTYPE && weaponType > WEAPONTYPE_UNARMED && CWeaponInfo::ms_aMaxAmmoForWeapon[weaponType] >= 0) { + if (weaponType < WEAPONTYPE_TOTALWEAPONS && weaponType > WEAPONTYPE_UNARMED && CWeaponInfo::ms_aMaxAmmoForWeapon[weaponType] >= 0) { // Looks like abandoned idea. This block never runs, ms_aMaxAmmoForWeapon is always -1. - GetWeapon(slot).m_nAmmoTotal = Min(CWeaponInfo::ms_aMaxAmmoForWeapon[weaponType], (int32)GetWeapon(slot).m_nAmmoTotal); + GetWeapon(slot).m_nAmmoTotal = Min(CWeaponInfo::ms_aMaxAmmoForWeapon[weaponType], GetWeapon(slot).m_nAmmoTotal); } else { GetWeapon(slot).m_nAmmoTotal = Min(99999, GetWeapon(slot).m_nAmmoTotal); } @@ -4966,7 +5103,7 @@ CPed::SetEvasiveStep(CEntity *reason, uint8 animType) else if (animType < 2) stepAnim = ANIM_EV_STEP; else - stepAnim = NUM_ANIMS; + stepAnim = NUM_STD_ANIMS; } if (!RpAnimBlendClumpGetAssociation(GetClump(), stepAnim)) { CAnimBlendAssociation *stepAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, stepAnim, 8.0f); @@ -5111,7 +5248,7 @@ CPed::SetAttack(CEntity *victim) return; if (curWeapon->m_bReload && - (RpAnimBlendClumpGetAssociation(GetClump(), ANIM_WEAPON_RELOAD) || RpAnimBlendClumpGetAssociation(GetClump(), ANIM_WEAPON_CROUCHRELOAD))) { + (RpAnimBlendClumpGetAssociation(GetClump(), GetReloadAnim(curWeapon)) || RpAnimBlendClumpGetAssociation(GetClump(), GetCrouchReloadAnim(curWeapon)))) { if (!IsPlayer() || m_nPedState != PED_ATTACK || ((CPlayerPed*)this)->m_bHaveTargetSelected) bIsAttacking = false; else @@ -5120,23 +5257,16 @@ CPed::SetAttack(CEntity *victim) return; } - // TODO(Miami): Brass knuckles - if (GetWeapon()->m_eWeaponType == WEAPONTYPE_UNARMED || curWeapon->m_bFightMode /* || GetWeapon()->m_eWeaponType == WEAPONTYPE_BRASSKNUCKLES */) { + if (GetWeapon()->m_eWeaponType == WEAPONTYPE_UNARMED || curWeapon->m_bFightMode || GetWeapon()->m_eWeaponType == WEAPONTYPE_BRASSKNUCKLE) { if (IsPlayer() || (m_nPedState != PED_FIGHT && m_nMoveState != PEDMOVE_NONE && m_nMoveState != PEDMOVE_STILL && !(m_pedStats->m_flags & STAT_SHOPPING_BAGS) && curWeapon->m_bPartialAttack)) { if (m_nPedState != PED_ATTACK) { - if (m_nPedState == PED_FOLLOW_PATH) - ClearFollowPath(); - - m_nPedState = PED_ATTACK; + SetPedState(PED_ATTACK); bIsAttacking = false; - // TODO(Miami): Revert when fighting got ported - animAssoc = CAnimManager::BlendAnimation(GetClump(), curWeapon->m_AnimToPlay, - GetWeapon()->m_eWeaponType == WEAPONTYPE_UNARMED ? ANIM_FIGHT_PPUNCH : ANIM_MELEE_ATTACK_START, 8.0f); - // CAnimBlendAssociation *animAssoc = CAnimManager::BlendAnimation(GetClump(), curWeapon->m_AnimToPlay, ANIM_MELEE_ATTACK_START, 8.0f); + CAnimBlendAssociation *animAssoc = CAnimManager::BlendAnimation(GetClump(), curWeapon->m_AnimToPlay, ANIM_MELEE_ATTACK_START, 8.0f); animAssoc->SetRun(); if (animAssoc->currentTime == animAssoc->hierarchy->totalLength) animAssoc->SetCurrentTime(0.0f); @@ -5154,10 +5284,7 @@ CPed::SetAttack(CEntity *victim) m_nMoveState == PEDMOVE_WALK || m_nMoveState == PEDMOVE_RUN)) { if (m_nPedState != PED_ATTACK) { - if (m_nPedState == PED_FOLLOW_PATH) - ClearFollowPath(); - - m_nPedState = PED_ATTACK; + SetPedState(PED_ATTACK); bIsAttacking = false; CAnimBlendAssociation* animAssoc = CAnimManager::BlendAnimation(GetClump(), curWeapon->m_AnimToPlay, ANIM_MELEE_ATTACK_START, 8.0f); animAssoc->SetRun(); @@ -5179,8 +5306,8 @@ CPed::SetAttack(CEntity *victim) aimPos += GetUp() * 0.35f; CEntity *obstacle = CWorld::TestSphereAgainstWorld(aimPos, 0.2f, nil, true, false, false, true, false, false); if (obstacle) { - if(gaTempSphereColPoints[0].surfaceB != SURFACE_SCAFFOLD && gaTempSphereColPoints[0].surfaceB != SURFACE_METAL_FENCE && - gaTempSphereColPoints[0].surfaceB != SURFACE_WOOD_BOX && gaTempSphereColPoints[0].surfaceB != SURFACE_METAL_POLE) { + if(gaTempSphereColPoints[0].surfaceB != SURFACE_TRANSPARENT_CLOTH && gaTempSphereColPoints[0].surfaceB != SURFACE_METAL_CHAIN_FENCE && + gaTempSphereColPoints[0].surfaceB != SURFACE_WOOD_BENCH && gaTempSphereColPoints[0].surfaceB != SURFACE_SCAFFOLD_POLE) { if (!IsPlayer()) { bObstacleShowedUpDuringKillObjective = true; m_shootTimer = 0; @@ -5234,19 +5361,16 @@ CPed::SetAttack(CEntity *victim) if (m_nPedState != PED_AIM_GUN) SetStoredState(); - if (m_nPedState == PED_FOLLOW_PATH) - ClearFollowPath(); - - m_nPedState = PED_ATTACK; + SetPedState(PED_ATTACK); SetMoveState(PEDMOVE_NONE); if (bCrouchWhenShooting && bIsDucking && !!curWeapon->m_bCrouchFire) { - CAnimBlendAssociation* curMoveAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_WEAPON_CROUCHFIRE); + CAnimBlendAssociation* curMoveAssoc = RpAnimBlendClumpGetAssociation(GetClump(), GetCrouchFireAnim(curWeapon)); if (curMoveAssoc) { - if (strcmp(CAnimManager::GetAnimAssociation(curWeapon->m_AnimToPlay, ANIM_WEAPON_CROUCHFIRE)->hierarchy->name, curMoveAssoc->hierarchy->name) != 0) { + if (strcmp(CAnimManager::GetAnimAssociation(curWeapon->m_AnimToPlay, GetCrouchFireAnim(curWeapon))->hierarchy->name, curMoveAssoc->hierarchy->name) != 0) { delete curMoveAssoc; } } - animAssoc = CAnimManager::BlendAnimation(GetClump(), curWeapon->m_AnimToPlay, ANIM_WEAPON_CROUCHFIRE, 8.0f); + animAssoc = CAnimManager::BlendAnimation(GetClump(), curWeapon->m_AnimToPlay, GetCrouchFireAnim(curWeapon), 8.0f); } else { float animDelta = 8.0f; if (curWeapon->m_eWeaponFire == WEAPON_FIRE_MELEE) @@ -5366,10 +5490,11 @@ CPed::StartFightAttack(uint8 buttonPressure) nPlayerInComboMove = 0; } +// --MIAMI: Done void CPed::LoadFightData(void) { - float startFireTime, endFireTime, comboFollowOnTime, strikeRadius; + float startFireTime, endFireTime, comboFollowOnTime, strikeRadius, extendReachMultiplier; int damage, flags; char line[256], moveName[32], animName[32], hitLevel; int moveId = 0; @@ -5398,12 +5523,13 @@ CPed::LoadFightData(void) sscanf( &line[lp], - "%s %f %f %f %f %c %s %d %d", + "%s %f %f %f %f %f %c %s %d %d", moveName, &startFireTime, &endFireTime, &comboFollowOnTime, &strikeRadius, + &extendReachMultiplier, &hitLevel, animName, &damage, @@ -5416,6 +5542,7 @@ CPed::LoadFightData(void) tFightMoves[moveId].endFireTime = endFireTime / 30.0f; tFightMoves[moveId].comboFollowOnTime = comboFollowOnTime / 30.0f; tFightMoves[moveId].strikeRadius = strikeRadius; + tFightMoves[moveId].extendReachMultiplier = extendReachMultiplier; tFightMoves[moveId].damage = damage; tFightMoves[moveId].flags = flags; @@ -5439,11 +5566,14 @@ CPed::LoadFightData(void) break; } - if (strncmp(animName, "null", 4) != 0) { - animAssoc = CAnimManager::GetAnimAssociation(ASSOCGRP_STD, animName); - tFightMoves[moveId].animId = (AnimationId)animAssoc->animId; - } else { - tFightMoves[moveId].animId = ANIM_WALK; + if (strncmp(animName, "default", 8) != 0) { + if (strncmp(animName, "null", 5) != 0) { + animAssoc = CAnimManager::GetAnimAssociation(ASSOCGRP_STD, animName); + tFightMoves[moveId].animId = (AnimationId)animAssoc->animId; + } + else { + tFightMoves[moveId].animId = ANIM_WALK; + } } moveId++; } @@ -5503,13 +5633,13 @@ CPed::FightStrike(CVector &touchedNodePos) for (int j = 0; j < hisCol->numSpheres; j++) { attackDistance = hisCol->spheres[j].center; attackDistance -= touchedNodePos; - CColSphere *ourPieces = hisCol->spheres; - float maxDistanceToBeat = ourPieces[j].radius + tFightMoves[m_lastFightMove].strikeRadius; + CColSphere *hisPieces = hisCol->spheres; + float maxDistanceToBeat = hisPieces[j].radius + tFightMoves[m_lastFightMove].strikeRadius; // We can beat him too if (sq(maxDistanceToBeat) > attackDistance.MagnitudeSqr()) { pedFound = true; - closestPedPiece = (ePedPieceTypes) ourPieces[j].piece; + closestPedPiece = (ePedPieceTypes) hisPieces[j].piece; break; } } @@ -5536,6 +5666,7 @@ CPed::FightStrike(CVector &touchedNodePos) damageMult *= m_pedStats->m_attackStrength; } + /* // Change direction if we used kick. if (m_lastFightMove == FIGHTMOVE_KICK) { if (CGeneral::GetRandomNumber() & 1) { @@ -5543,7 +5674,7 @@ CPed::FightStrike(CVector &touchedNodePos) if (direction > 3) direction -= 4; } - } + } */ nearPed->ReactToAttack(this); // Mostly unused. if > 5, ANIM_HIT_WALK will be run, that's it. @@ -5720,7 +5851,7 @@ CPed::SetFlee(CVector2D const &from, int time) void CPed::SetWaitState(eWaitState state, void *time) { - AnimationId waitAnim = NUM_ANIMS; + AnimationId waitAnim = NUM_STD_ANIMS; CAnimBlendAssociation *animAssoc; if (!IsPedInControl()) @@ -5807,10 +5938,10 @@ CPed::SetWaitState(eWaitState state, void *time) case WAITSTATE_PLAYANIM_COWER: waitAnim = ANIM_HANDSCOWER; case WAITSTATE_PLAYANIM_HANDSUP: - if (waitAnim == NUM_ANIMS) + if (waitAnim == NUM_STD_ANIMS) waitAnim = ANIM_HANDSUP; case WAITSTATE_PLAYANIM_HANDSCOWER: - if (waitAnim == NUM_ANIMS) + if (waitAnim == NUM_STD_ANIMS) waitAnim = ANIM_HANDSCOWER; m_headingRate = 0.0f; if (time) @@ -5824,10 +5955,10 @@ CPed::SetWaitState(eWaitState state, void *time) case WAITSTATE_PLAYANIM_DUCK: waitAnim = ANIM_DUCK_DOWN; case WAITSTATE_PLAYANIM_TAXI: - if (waitAnim == NUM_ANIMS) + if (waitAnim == NUM_STD_ANIMS) waitAnim = ANIM_IDLE_TAXI; case WAITSTATE_PLAYANIM_CHAT: - if (waitAnim == NUM_ANIMS) + if (waitAnim == NUM_STD_ANIMS) waitAnim = ANIM_IDLE_CHAT; if (time) m_nWaitTimer = CTimer::GetTimeInMilliseconds() + *(int*)time; @@ -5846,8 +5977,44 @@ CPed::SetWaitState(eWaitState state, void *time) m_nWaitTimer = CTimer::GetTimeInMilliseconds() + 2500; CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_IDLE_TIRED, 4.0f); break; + case WAITSTATE_SIT_DOWN: + animAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_SEAT_DOWN, 4.0f); + animAssoc->SetFinishCallback(FinishedWaitCB, this); + m_nWaitTimer = CTimer::GetTimeInMilliseconds() + 10000; + break; + case WAITSTATE_SIT_UP: + animAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_SEAT_UP, 4.0f); + animAssoc->SetFinishCallback(FinishedWaitCB, this); + m_nWaitTimer = CTimer::GetTimeInMilliseconds() + 100000; + break; + case WAITSTATE_SIT_IDLE: + animAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_SEAT_IDLE, 5000.0f); + animAssoc->SetFinishCallback(FinishedWaitCB, this); + if (time) + m_nWaitTimer = CTimer::GetTimeInMilliseconds() + *(int*)time; + else + m_nWaitTimer = CTimer::GetTimeInMilliseconds() + CGeneral::GetRandomNumberInRange(25000, 30000); + break; + case WAITSTATE_USE_ATM: + animAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_ATM, 5000.0f); + animAssoc->SetFinishCallback(FinishedWaitCB, this); + if (time) + m_nWaitTimer = CTimer::GetTimeInMilliseconds() + *(int*)time; + else + m_nWaitTimer = CTimer::GetTimeInMilliseconds() + 100000; + break; + case WAITSTATE_SUN_BATHE_PRE: + case WAITSTATE_SUN_BATHE_DOWN: + case WAITSTATE_SUN_BATHE_IDLE: + case WAITSTATE_RIOT: + case WAITSTATE_FAST_FALL: + case WAITSTATE_BOMBER: + case WAITSTATE_STRIPPER: + case WAITSTATE_GROUND_ATTACK: + case WAITSTATE_LANCESITTING: + case WAITSTATE_PLAYANIM_HANDSUP_SIMPLE: default: - m_nWaitState = WAITSTATE_FALSE; + ClearWaitState(); RestoreHeadingRate(); return; } @@ -5873,7 +6040,7 @@ CPed::PlayHitSound(CPed *hitTo) S42 = SOUND_FIGHT_PUNCH_FROM_BEHIND_42, S43 = SOUND_FIGHT_KNEE_OR_KICK_43, S44 = SOUND_FIGHT_KICK_44, - NO_SND = SOUND_TOTAL_PED_SOUNDS + NO_SND = SOUND_NO_SOUND }; uint16 hitSoundsByFightMoves[12][10] = { {S39,S42,S43,S43,S39,S39,S39,S39,S39,S42}, @@ -6246,6 +6413,7 @@ CPed::CollideWithPed(CPed *collideWith) } } +// --MIAMI: Done except commented thing void CPed::CreateDeadPedMoney(void) { @@ -6253,36 +6421,74 @@ CPed::CreateDeadPedMoney(void) return; int skin = GetModelIndex(); + + // TODO(Miami): New flag if ((skin >= MI_COP && skin <= MI_FIREMAN) || CharCreatedBy == MISSION_CHAR || bInVehicle) return; - int money = CGeneral::GetRandomNumber() % 60; + int money = m_nPedMoney; if (money < 10) return; - if (money == 43) - money = 700; + CVector pickupPos = GetPosition(); + CPickups::CreateSomeMoney(pickupPos, money); + m_nPedMoney = 0; +} - int pickupCount = money / 40 + 1; - int moneyPerPickup = money / pickupCount; +void +CPed::CreateDeadPedPickupCoors(float *x, float *y, float *z) +{ + bool found = false; + CVector pickupPos; - for(int i = 0; i < pickupCount; i++) { - // (CGeneral::GetRandomNumber() % 256) * PI / 128 gives a float up to something TWOPI-ish. - float pickupX = 1.5f * Sin((CGeneral::GetRandomNumber() % 256) * PI / 128) + GetPosition().x; - float pickupY = 1.5f * Cos((CGeneral::GetRandomNumber() % 256) * PI / 128) + GetPosition().y; - bool found = false; - float groundZ = CWorld::FindGroundZFor3DCoord(pickupX, pickupY, GetPosition().z, &found) + 0.5f; - if (found) { - CPickups::GenerateNewOne(CVector(pickupX, pickupY, groundZ), MI_MONEY, PICKUP_MONEY, moneyPerPickup + (CGeneral::GetRandomNumber() & 7)); +#define NUMBER_OF_ATTEMPTS 32 + for (int i = 0; i < NUMBER_OF_ATTEMPTS; i++) { + + pickupPos = GetPosition(); + pickupPos.x = 1.5f * Sin((CGeneral::GetRandomNumber() % 256) * PI / 128) + GetPosition().x; + pickupPos.y = 1.5f * Cos((CGeneral::GetRandomNumber() % 256) * PI / 128) + GetPosition().y; + pickupPos.z = CWorld::FindGroundZFor3DCoord(pickupPos.x, pickupPos.y, pickupPos.z, &found) + 0.5f; + + if (!found) + continue; + + CVector pedPos = GetPosition(); + pedPos.z += 0.3f; + + CVector pedToPickup = pickupPos - pedPos; + float distance = pedToPickup.Magnitude(); + + // outer edge of pickup + distance = (distance + 0.4f) / distance; + CVector pickupPos2 = pedPos; + pickupPos2 += distance * pedToPickup; + + if ((pickupPos - FindPlayerCoors()).Magnitude2D() > 2.0f || i > NUMBER_OF_ATTEMPTS / 2) { + + if (i > NUMBER_OF_ATTEMPTS / 2 || !CPickups::TestForPickupsInBubble(pickupPos, 1.3f)) { + + if (CWorld::GetIsLineOfSightClear(pickupPos2, pedPos, + true, i < NUMBER_OF_ATTEMPTS / 2, false, i < NUMBER_OF_ATTEMPTS / 2, false, false, false)) { + + if (i > NUMBER_OF_ATTEMPTS / 2 || !CWorld::TestSphereAgainstWorld(pickupPos, 1.2f, nil, false, true, false, false, false, false)) { + *x = pickupPos.x; + *y = pickupPos.y; + *z = pickupPos.z; + return; + } + } + } } } + *x = GetPosition().x; + *y = GetPosition().y; + *z = GetPosition().z + 0.4f; +#undef NUMBER_OF_ATTEMPTS } void CPed::CreateDeadPedWeaponPickups(void) { - bool found = false; - float angleToPed; CVector pickupPos; if (bInVehicle) @@ -6292,37 +6498,14 @@ CPed::CreateDeadPedWeaponPickups(void) eWeaponType weapon = GetWeapon(i).m_eWeaponType; int weaponAmmo = GetWeapon(i).m_nAmmoTotal; - if (weapon == WEAPONTYPE_UNARMED || weapon == WEAPONTYPE_DETONATOR || weaponAmmo == 0) + if (weapon == WEAPONTYPE_UNARMED || weapon == WEAPONTYPE_DETONATOR || (weaponAmmo == 0 && !GetWeapon(i).IsTypeMelee())) continue; - angleToPed = i * 1.75f; - pickupPos = GetPosition(); - pickupPos.x += 1.5f * Sin(angleToPed); - pickupPos.y += 1.5f * Cos(angleToPed); - pickupPos.z = CWorld::FindGroundZFor3DCoord(pickupPos.x, pickupPos.y, pickupPos.z, &found) + 0.5f; - - CVector pedPos = GetPosition(); - pedPos.z += 0.3f; - - CVector pedToPickup = pickupPos - pedPos; - float distance = pedToPickup.Magnitude(); - - // outer edge of pickup - distance = (distance + 0.3f) / distance; - CVector pickupPos2 = pedPos; - pickupPos2 += distance * pedToPickup; - - // pickup must be on ground and line to its edge must be clear - if (!found || CWorld::GetIsLineOfSightClear(pickupPos2, pedPos, true, false, false, false, false, false, false)) { - // otherwise try another position (but disregard second check apparently) - angleToPed += 3.14f; - pickupPos = GetPosition(); - pickupPos.x += 1.5f * Sin(angleToPed); - pickupPos.y += 1.5f * Cos(angleToPed); - pickupPos.z = CWorld::FindGroundZFor3DCoord(pickupPos.x, pickupPos.y, pickupPos.z, &found) + 0.5f; + int quantity = Min(weaponAmmo, AmmoForWeapon_OnStreet[weapon] / 2); + CreateDeadPedPickupCoors(&pickupPos.x, &pickupPos.y, &pickupPos.z); + if (!CPickups::TryToMerge_WeaponType(pickupPos, weapon, PICKUP_ONCE_TIMEOUT, quantity, false)) { + CPickups::GenerateNewOne_WeaponType(pickupPos, weapon, PICKUP_ONCE_TIMEOUT, Min(weaponAmmo, quantity)); } - if (found) - CPickups::GenerateNewOne_WeaponType(pickupPos, weapon, PICKUP_ONCE_TIMEOUT, Min(weaponAmmo, AmmoForWeapon_OnStreet[weapon])); } ClearWeapons(); } @@ -6420,13 +6603,6 @@ CPed::RemoveWeaponAnims(int unused, float animDelta) CAnimBlendAssociation *weaponAssoc; //CWeaponInfo::GetWeaponInfo(unused); - // TODO(Miami): Remove when fighting got ported - weaponAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_FIGHT_PPUNCH); - if (weaponAssoc) { - weaponAssoc->blendDelta = animDelta; - weaponAssoc->flags |= ASSOC_DELETEFADEDOUT; - } - weaponAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_WEAPON_FIRE); if (weaponAssoc) { weaponAssoc->blendDelta = animDelta; @@ -6468,10 +6644,7 @@ CPed::SetDead(void) if (m_nPedState == PED_DRIVING) bIsVisible = false; - if (m_nPedState == PED_FOLLOW_PATH) - ClearFollowPath(); - - m_nPedState = PED_DEAD; + SetPedState(PED_DEAD); m_pVehicleAnim = nil; m_pCollidingEntity = nil; @@ -6522,11 +6695,7 @@ CPed::SetSeek(CVector pos, float distanceToCountDone) || (m_nPedState == PED_SEEK_POS && m_vecSeekPos.x == pos.x && m_vecSeekPos.y == pos.y)) return; - if (GetWeapon()->m_eWeaponType == WEAPONTYPE_M16 - || GetWeapon()->m_eWeaponType == WEAPONTYPE_AK47 - || GetWeapon()->m_eWeaponType == WEAPONTYPE_SNIPERRIFLE - || GetWeapon()->m_eWeaponType == WEAPONTYPE_ROCKETLAUNCHER - || GetWeapon()->m_eWeaponType == WEAPONTYPE_SHOTGUN) { + if (!CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType)->m_bCanAimWithArm) { ClearPointGunAt(); } @@ -6587,6 +6756,7 @@ CPed::DoesLOSBulletHitPed(CColPoint &colPoint) return retVal; } +// TODO(Miami): Ducking doesn't work, fix this bool CPed::DuckAndCover(void) { @@ -6604,9 +6774,11 @@ CPed::DuckAndCover(void) SetAimFlag(m_pedInObjective); } else { - bCrouchWhenShooting = false; bKindaStayInSamePlace = false; - bIsDucking = false; + if (bIsDucking) + ClearDuck(true); + + bCrouchWhenShooting = false; bDuckAndCover = false; m_headingRate = 10.0f; m_duckAndCoverTimer = CTimer::GetTimeInMilliseconds() + CGeneral::GetRandomNumberInRange(20000,30000); @@ -6619,8 +6791,11 @@ CPed::DuckAndCover(void) bool justDucked = false; CVehicle *foundVeh = nil; float maxDist = 225.0f; - bIsDucking = false; + if (bIsDucking) + ClearDuck(true); + bCrouchWhenShooting = false; + if (CTimer::GetTimeInMilliseconds() > m_leaveCarTimer) { CVector pos = GetPosition(); int16 lastVehicle; @@ -7009,13 +7184,9 @@ CPed::Fight(void) case FIGHTMOVE_KNEE: TransformToNode(touchingNodePos, PED_LOWERLEGR); break; - case FIGHTMOVE_HEADBUTT: - TransformToNode(touchingNodePos, PED_HEAD); - break; case FIGHTMOVE_PUNCHJAB: TransformToNode(touchingNodePos, PED_HANDL); break; - case FIGHTMOVE_KICK: case FIGHTMOVE_LONGKICK: case FIGHTMOVE_ROUNDHOUSE: case FIGHTMOVE_GROUNDKICK: @@ -7076,12 +7247,12 @@ CPed::Fight(void) canRoundhouse = false; punchOnly = false; canKick = true; - nextFightMove = (m_fightButtonPressure > 190 ? FIGHTMOVE_HEADBUTT : FIGHTMOVE_KNEE); + nextFightMove = (m_fightButtonPressure > 190 ? FIGHTMOVE_BODYBLOW : FIGHTMOVE_KNEE); hasShoppingBags = false; canKneeHead = true; nPlayerInComboMove = 0; } else { - nextFightMove = (m_fightButtonPressure > 120 ? FIGHTMOVE_HEADBUTT : FIGHTMOVE_KNEE); + nextFightMove = (m_fightButtonPressure > 120 ? FIGHTMOVE_BODYBLOW : FIGHTMOVE_KNEE); uint16 pedFeatures = m_pedStats->m_flags; punchOnly = pedFeatures & STAT_PUNCH_ONLY; canRoundhouse = pedFeatures & STAT_CAN_ROUNDHOUSE; @@ -7120,7 +7291,7 @@ CPed::Fight(void) && neededTurn < DEGTORAD(35.0f) && (canKick || hasShoppingBags)) { - nextFightMove = FIGHTMOVE_KICK; + nextFightMove = FIGHTMOVE_LONGKICK; if (hasShoppingBags) { nextFightMove = FIGHTMOVE_ROUNDHOUSE; } else if (canRoundhouse && CGeneral::GetRandomNumber() & 1) { @@ -7213,7 +7384,7 @@ CPed::Fight(void) if (fightingPedDist >= 1.3f) { if (fightingPedDist < 1.7f && canKick) { - nextFightMove = FIGHTMOVE_KICK; + nextFightMove = FIGHTMOVE_LONGKICK; if (canRoundhouse && CGeneral::GetRandomNumber() & 1) nextFightMove = FIGHTMOVE_ROUNDHOUSE; @@ -7547,12 +7718,12 @@ CPed::FinishedWaitCB(CAnimBlendAssociation *animAssoc, void *arg) void CPed::Wait(void) { - AnimationId mustHaveAnim = NUM_ANIMS; + AnimationId mustHaveAnim = NUM_STD_ANIMS; CAnimBlendAssociation *animAssoc; CPed *pedWeLook; if (DyingOrDead()) { - m_nWaitState = WAITSTATE_FALSE; + ClearWaitState(); RestoreHeadingRate(); return; } @@ -7562,7 +7733,7 @@ CPed::Wait(void) case WAITSTATE_TRAFFIC_LIGHTS: if (CTimer::GetTimeInMilliseconds() > m_nWaitTimer) { if (CTrafficLights::LightForPeds() == PED_LIGHTS_WALK) { - m_nWaitState = WAITSTATE_FALSE; + ClearWaitState(); SetMoveState(PEDMOVE_WALK); } } @@ -7571,7 +7742,7 @@ CPed::Wait(void) case WAITSTATE_CROSS_ROAD: if (CTimer::GetTimeInMilliseconds() > m_nWaitTimer) { if (CGeneral::GetRandomNumber() & 1 || !m_nWaitTimer) - m_nWaitState = WAITSTATE_FALSE; + ClearWaitState(); else SetWaitState(WAITSTATE_CROSS_ROAD_LOOK, nil); @@ -7585,7 +7756,7 @@ CPed::Wait(void) case WAITSTATE_CROSS_ROAD_LOOK: if (CTimer::GetTimeInMilliseconds() > m_nWaitTimer) { - m_nWaitState = WAITSTATE_FALSE; + ClearWaitState(); animAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_ROAD_CROSS); if (animAssoc) { animAssoc->blendDelta = -8.0f; @@ -7602,7 +7773,7 @@ CPed::Wait(void) CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_XPRESS_SCRATCH, 4.0f); } } else { - m_nWaitState = WAITSTATE_FALSE; + ClearWaitState(); SetMoveState(PEDMOVE_WALK); } break; @@ -7613,13 +7784,13 @@ CPed::Wait(void) m_collidingThingTimer = CTimer::GetTimeInMilliseconds() + 2500; } } else { - m_nWaitState = WAITSTATE_FALSE; + ClearWaitState(); } break; case WAITSTATE_TURN180: if (CTimer::GetTimeInMilliseconds() > m_nWaitTimer) { - m_nWaitState = WAITSTATE_FALSE; + ClearWaitState(); SetMoveState(PEDMOVE_WALK); m_fRotationCur = m_fRotationCur + PI; if (m_nPedState == PED_INVESTIGATE) @@ -7638,7 +7809,7 @@ CPed::Wait(void) animAssoc->SetFinishCallback(FinishedWaitCB, this); m_nWaitTimer = CTimer::GetTimeInMilliseconds() + 5000; } else { - m_nWaitState = WAITSTATE_FALSE; + ClearWaitState(); } } break; @@ -7667,7 +7838,7 @@ CPed::Wait(void) if (animAssoc->animId == ANIM_TURN_180) { m_fRotationCur = CGeneral::LimitRadianAngle(PI + m_fRotationCur); - m_nWaitState = WAITSTATE_FALSE; + ClearWaitState(); SetMoveState(PEDMOVE_WALK); m_nStoredMoveState = PEDMOVE_NONE; m_panicCounter = 0; @@ -7704,7 +7875,7 @@ CPed::Wait(void) case WAITSTATE_LOOK_ABOUT: if (CTimer::GetTimeInMilliseconds() > m_nWaitTimer) { - m_nWaitState = WAITSTATE_FALSE; + ClearWaitState(); animAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_IDLE_HBHB); if (animAssoc) { animAssoc->blendDelta = -8.0f; @@ -7717,7 +7888,7 @@ CPed::Wait(void) mustHaveAnim = ANIM_HANDSUP; case WAITSTATE_PLAYANIM_HANDSCOWER: - if (mustHaveAnim == NUM_ANIMS) + if (mustHaveAnim == NUM_STD_ANIMS) mustHaveAnim = ANIM_HANDSCOWER; animAssoc = RpAnimBlendClumpGetAssociation(GetClump(), mustHaveAnim); @@ -7731,7 +7902,7 @@ CPed::Wait(void) TurnBody(); } else { - m_nWaitState = WAITSTATE_FALSE; + ClearWaitState(); m_nWaitTimer = 0; if (m_pLookTarget && m_pLookTarget->IsPed()) { @@ -7789,15 +7960,15 @@ CPed::Wait(void) mustHaveAnim = ANIM_HANDSCOWER; case WAITSTATE_PLAYANIM_DUCK: - if (mustHaveAnim == NUM_ANIMS) + if (mustHaveAnim == NUM_STD_ANIMS) mustHaveAnim = ANIM_DUCK_DOWN; case WAITSTATE_PLAYANIM_TAXI: - if (mustHaveAnim == NUM_ANIMS) + if (mustHaveAnim == NUM_STD_ANIMS) mustHaveAnim = ANIM_IDLE_TAXI; case WAITSTATE_PLAYANIM_CHAT: - if (mustHaveAnim == NUM_ANIMS) + if (mustHaveAnim == NUM_STD_ANIMS) mustHaveAnim = ANIM_IDLE_CHAT; if (CTimer::GetTimeInMilliseconds() > m_nWaitTimer) { @@ -7806,7 +7977,7 @@ CPed::Wait(void) animAssoc->blendDelta = -4.0f; animAssoc->flags |= ASSOC_DELETEFADEDOUT; } - m_nWaitState = WAITSTATE_FALSE; + ClearWaitState(); } #ifdef VC_PED_PORTS else if (m_nWaitState == WAITSTATE_PLAYANIM_TAXI) { @@ -7830,13 +8001,59 @@ CPed::Wait(void) animAssoc->flags |= ASSOC_DELETEFADEDOUT; CAnimManager::BlendAnimation(GetClump(), m_animGroup, ANIM_IDLE_STANCE, 4.0f); int timer = 2000; - m_nWaitState = WAITSTATE_FALSE; + ClearWaitState(); SetWaitState(WAITSTATE_CROSS_ROAD_LOOK, &timer); } } else { - m_nWaitState = WAITSTATE_FALSE; + ClearWaitState(); } break; + case WAITSTATE_SIT_DOWN: + if (CTimer::GetTimeInMilliseconds() > m_nWaitTimer) { + ClearWaitState(); + SetWaitState(WAITSTATE_SIT_IDLE, 0); + } + break; + //case WAITSTATE_SIT_DOWN_RVRS: + case WAITSTATE_SIT_UP: + if (CTimer::GetTimeInMilliseconds() > m_nWaitTimer) { + if (m_attractor) + GetPedAttractorManager()->BroadcastDeparture(this, m_attractor); + ClearWaitState(); + //TODO(MIAMI): scan for threats! + } + break; + case WAITSTATE_SIT_IDLE: + if (bTurnedAroundOnAttractor) { + m_fRotationCur += PI; + m_fRotationCur = CGeneral::LimitRadianAngle(m_fRotationCur); + m_fRotationDest = m_fRotationCur; + bTurnedAroundOnAttractor = false; + } + // TODO(MIAMI): scan for threats! + if (CTimer::GetTimeInMilliseconds() > m_nWaitTimer) { + ClearWaitState(); + SetWaitState(WAITSTATE_SIT_UP, 0); + } + break; + case WAITSTATE_USE_ATM: + if (CTimer::GetTimeInMilliseconds() > m_nWaitTimer) { + if (m_attractor) + GetPedAttractorManager()->BroadcastDeparture(this, m_attractor); + ClearWaitState(); + } + break; + case WAITSTATE_SUN_BATHE_PRE: + case WAITSTATE_SUN_BATHE_DOWN: + case WAITSTATE_SUN_BATHE_IDLE: + case WAITSTATE_RIOT: + case WAITSTATE_FAST_FALL: + case WAITSTATE_BOMBER: + case WAITSTATE_STRIPPER: + case WAITSTATE_GROUND_ATTACK: + case WAITSTATE_LANCESITTING: + case WAITSTATE_PLAYANIM_HANDSUP_SIMPLE: + assert(0); default: break; } @@ -8539,14 +8756,22 @@ CPed::SetLanding(void) CAnimBlendAssociation *fallAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_FALL_FALL); CAnimBlendAssociation *landAssoc; + if (fallAssoc && bIsDrowning) + return; + RpAnimBlendClumpSetBlendDeltas(GetClump(), ASSOC_PARTIAL, -1000.0f); - if (fallAssoc) { + if (fallAssoc || m_nPedType == PEDTYPE_COP && bKnockedUpIntoAir) { landAssoc = CAnimManager::AddAnimation(GetClump(), ASSOCGRP_STD, ANIM_FALL_COLLAPSE); DMAudio.PlayOneShot(m_audioEntityId, SOUND_FALL_COLLAPSE, 1.0f); if (IsPlayer()) Say(SOUND_PED_LAND); + if (m_nPedType == PEDTYPE_COP) { + if (bKnockedUpIntoAir) + bKnockedUpIntoAir = false; + } + } else { landAssoc = CAnimManager::AddAnimation(GetClump(), ASSOCGRP_STD, ANIM_FALL_LAND); DMAudio.PlayOneShot(m_audioEntityId, SOUND_FALL_LAND, 1.0f); @@ -8854,7 +9079,11 @@ CPed::InvestigateEvent(void) bool CPed::IsPedDoingDriveByShooting(void) { +#ifdef FIX_BUGS if (FindPlayerPed() == this && CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType)->m_nWeaponSlot == 5) { +#else + if (FindPlayerPed() == this && GetWeapon()->m_eWeaponType == WEAPONTYPE_UZI) { +#endif if (TheCamera.Cams[TheCamera.ActiveCam].LookingLeft || TheCamera.Cams[TheCamera.ActiveCam].LookingRight) return true; } @@ -9140,7 +9369,7 @@ CPed::KillPedWithCar(CVehicle *car, float impulse) void CPed::Look(void) { - // UNUSED: This is a perfectly empty function. + TurnBody(); } bool @@ -9485,7 +9714,7 @@ CPed::MoveHeadToLook(void) } if (m_pLookTarget->IsPed()) { - ((CPed*)m_pLookTarget)->m_pedIK.GetComponentPosition((RwV3d*) &lookPos, PED_MID); + ((CPed*)m_pLookTarget)->m_pedIK.GetComponentPosition(*(RwV3d *)&lookPos, PED_MID); } else { lookPos = m_pLookTarget->GetPosition(); } @@ -9505,7 +9734,7 @@ CPed::MoveHeadToLook(void) bool notRocketLauncher = false; bool notTwoHanded = false; - AnimationId animToPlay = NUM_ANIMS; + AnimationId animToPlay = NUM_STD_ANIMS; if (!GetWeapon()->IsType2Handed()) notTwoHanded = true; @@ -9534,7 +9763,7 @@ CPed::MoveHeadToLook(void) animToPlay = ANIM_FUCKU; } - if (animToPlay != NUM_ANIMS) { + if (animToPlay != NUM_STD_ANIMS) { CAnimBlendAssociation *newAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, animToPlay, 4.0f); if (newAssoc) { @@ -9726,6 +9955,7 @@ CPed::ProcessControl(void) bIsShooting = false; BuildPedLists(); bIsInWater = false; + bIsDrowning = false; ProcessBuoyancy(); if (m_nPedState != PED_ARRESTED) { @@ -9837,7 +10067,7 @@ CPed::ProcessControl(void) } else if (m_nPedStateTimer < 1001) { m_nPedStateTimer = 0; } - } else { + } else if (!GetPedAttractorManager()->IsInQueue(this, m_attractor)) { if (m_panicCounter == 50 && IsPedInControl()) { SetWaitState(WAITSTATE_STUCK, nil); // Leftover @@ -9891,11 +10121,8 @@ CPed::ProcessControl(void) if (m_nPedState == PED_FOLLOW_PATH) { if (DotProduct(m_vecDamageNormal, GetForward()) < -0.866f && CanPedJumpThis(collidingEnt, &m_vecDamageNormal)) { SetJump(); - - // Moved break into here, for compatibility with III - break; } - // break; + break; } #endif if (m_pedInObjective && @@ -10477,7 +10704,7 @@ CPed::ProcessControl(void) flyDir = 1; } - if (flyDir != 0 && !bSomeVCflag1) { + if (flyDir != 0 && !bHeadStuckInCollision) { SetPosition((flyDir == 2 ? obstacleForFlyingOtherDir.point : obstacleForFlying.point)); GetMatrix().GetPosition().z += FEET_OFFSET; GetMatrix().UpdateRW(); @@ -10584,11 +10811,11 @@ CPed::ProcessControl(void) if (CWorld::ProcessVerticalLine(offsetToCheck, GetPosition().z - FEET_OFFSET, foundCol, foundEnt, true, true, false, true, false, false, nil)) { #ifdef VC_PED_PORTS - if (!bSomeVCflag1 || FEET_OFFSET + foundCol.point.z < GetPosition().z) { + if (!bHeadStuckInCollision || FEET_OFFSET + foundCol.point.z < GetPosition().z) { GetMatrix().GetPosition().z = FEET_OFFSET + foundCol.point.z; GetMatrix().UpdateRW(); - if (bSomeVCflag1) - bSomeVCflag1 = false; + if (bHeadStuckInCollision) + bHeadStuckInCollision = false; } #else GetMatrix().GetPosition().z = FEET_OFFSET + foundCol.point.z; @@ -10658,15 +10885,15 @@ CPed::ProcessControl(void) if (IsPedInControl() && !bIsStanding && !m_pDamageEntity && CheckIfInTheAir()) { SetInTheAir(); #ifdef VC_PED_PORTS - bSomeVCflag1 = false; + bHeadStuckInCollision = false; #endif } #ifdef VC_PED_PORTS - if (bSomeVCflag1) { + if (bHeadStuckInCollision) { CVector posToCheck = GetPosition(); posToCheck.z += 0.9f; if (!CWorld::TestSphereAgainstWorld(posToCheck, 0.2f, this, true, true, false, true, false, false)) - bSomeVCflag1 = false; + bHeadStuckInCollision = false; } #endif ProcessObjective(); @@ -10866,15 +11093,13 @@ CPed::ProcessControl(void) return; } - if (m_pMyVehicle->pDriver != this || m_pMyVehicle->IsBoat()) { + if (m_pMyVehicle->pDriver != this) { LookForSexyPeds(); LookForSexyCars(); break; } - if (m_pMyVehicle->m_vehType == VEHICLE_TYPE_BIKE || !m_pMyVehicle->pDriver->IsPlayer()) { - break; - } + // TODO(Miami): Start KILL_CHAR_ON_BOAT objective CPad* pad = CPad::GetPad(0); @@ -10904,12 +11129,24 @@ CPed::ProcessControl(void) } } #endif + + // TODO(Miami): This part moved to DriveVehicle in VC float steerAngle = m_pMyVehicle->m_fSteerAngle; CAnimBlendAssociation *lDriveAssoc; CAnimBlendAssociation *rDriveAssoc; CAnimBlendAssociation *lbAssoc; CAnimBlendAssociation *sitAssoc; - if (m_pMyVehicle->bLowVehicle) { + if (m_pMyVehicle->IsBoat() && !(m_pMyVehicle->pHandling->Flags & HANDLING_SIT_IN_BOAT)) { + sitAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_DRIVE_BOAT); + + if (!sitAssoc || sitAssoc->blendAmount < 1.0f) { + break; + } + + lDriveAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_DRIVE_BOAT_L); + rDriveAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_DRIVE_BOAT_R); + lbAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_BOAT_LB); + } else if (m_pMyVehicle->bLowVehicle) { sitAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_CAR_LSIT); if (!sitAssoc || sitAssoc->blendAmount < 1.0f) { @@ -10929,18 +11166,21 @@ CPed::ProcessControl(void) lDriveAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_DRIVE_L); rDriveAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_DRIVE_R); lbAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_CAR_LB); + } - if (lbAssoc && - TheCamera.Cams[TheCamera.ActiveCam].Mode == CCam::MODE_1STPERSON - && TheCamera.Cams[TheCamera.ActiveCam].DirectionWasLooking == LOOKING_LEFT) { - lbAssoc->blendDelta = -1000.0f; - } + if (lbAssoc && + TheCamera.Cams[TheCamera.ActiveCam].Mode == CCam::MODE_1STPERSON + && TheCamera.Cams[TheCamera.ActiveCam].DirectionWasLooking == LOOKING_LEFT) { + lbAssoc->blendDelta = -1000.0f; } CAnimBlendAssociation *driveByAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_DRIVEBY_L); - if (!driveByAssoc) driveByAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_DRIVEBY_R); + if (!driveByAssoc) + driveByAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_DRIVEBY_LOW_L); + if (!driveByAssoc) + driveByAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_DRIVEBY_LOW_R); if (m_pMyVehicle->bLowVehicle || m_pMyVehicle->m_fGasPedal >= 0.0f || driveByAssoc) { if (steerAngle == 0.0f || driveByAssoc) { @@ -10955,6 +11195,8 @@ CPed::ProcessControl(void) if (rDriveAssoc) rDriveAssoc->blendAmount = clamp(steerAngle * -100.0f / 61.0f, 0.0f, 1.0f); + else if (m_pMyVehicle->IsBoat() && !(m_pMyVehicle->pHandling->Flags & HANDLING_SIT_IN_BOAT)) + CAnimManager::AddAnimation(GetClump(), ASSOCGRP_STD, ANIM_DRIVE_BOAT_R); else if (m_pMyVehicle->bLowVehicle) CAnimManager::AddAnimation(GetClump(), ASSOCGRP_STD, ANIM_DRIVE_LOW_R); else @@ -10966,6 +11208,8 @@ CPed::ProcessControl(void) if (lDriveAssoc) lDriveAssoc->blendAmount = clamp(steerAngle * 100.0f / 61.0f, 0.0f, 1.0f); + else if (m_pMyVehicle->IsBoat() && !(m_pMyVehicle->pHandling->Flags & HANDLING_SIT_IN_BOAT)) + CAnimManager::AddAnimation(GetClump(), ASSOCGRP_STD, ANIM_DRIVE_BOAT_L); else if (m_pMyVehicle->bLowVehicle) CAnimManager::AddAnimation(GetClump(), ASSOCGRP_STD, ANIM_DRIVE_LOW_L); else @@ -10978,10 +11222,18 @@ CPed::ProcessControl(void) if ((TheCamera.Cams[TheCamera.ActiveCam].Mode != CCam::MODE_1STPERSON || TheCamera.Cams[TheCamera.ActiveCam].DirectionWasLooking != LOOKING_LEFT) - && (!lbAssoc || lbAssoc->blendAmount < 1.0f)) { - CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_CAR_LB, 4.0f); + && (!lbAssoc || lbAssoc->blendAmount < 1.0f && lbAssoc->blendDelta <= 0.0f)) { + + if(m_pMyVehicle->IsBoat() && !(m_pMyVehicle->pHandling->Flags & HANDLING_SIT_IN_BOAT)) + CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_BOAT_LB, 4.0f); + else + CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_CAR_LB, 4.0f); } } + + // TODO(Miami): This part belongs to DriveVehicle + if (!m_pMyVehicle) + return; break; } case PED_DIE: @@ -11001,8 +11253,11 @@ CPed::ProcessControl(void) default: break; } SetMoveAnim(); - if (bPedIsBleeding) { + if (bPedIsBleeding || m_bleedCounter != 0) { if (CGame::nastyGame) { + if (m_bleedCounter != 0) + m_bleedCounter--; + if (!(CTimer::GetFrameCounter() & 3)) { CVector cameraDist = GetPosition() - TheCamera.GetPosition(); if (cameraDist.MagnitudeSqr() < sq(50.0f)) { @@ -11033,7 +11288,8 @@ CPed::ProcessControl(void) } m_pCurrentPhysSurface = nil; } - } + } else + ServiceTalking(); } void @@ -11054,11 +11310,28 @@ CPed::SetInTheAir(void) } +// --MIAMI: Done void CPed::RestoreHeadPosition(void) { + // TODO(Miami): This is inlined CanUseTorsoWhenLooking + bool canUseMyBody = false; + if (m_nPedState != PED_DRIVING && m_nPedState != PED_DRAG_FROM_CAR && !bIsDucking) { + if (m_animGroup != ASSOCGRP_SEXYWOMAN && m_animGroup != ASSOCGRP_WOMAN) + canUseMyBody = true; + } + if (!canUseMyBody) + m_pedIK.m_flags |= CPedIK::LOOKAROUND_HEAD_ONLY; + if (m_pedIK.RestoreLookAt()) { bIsRestoringLook = false; + canUseMyBody = false; + if (m_nPedState != PED_DRIVING && m_nPedState != PED_DRAG_FROM_CAR && !bIsDucking) { + if (m_animGroup != ASSOCGRP_SEXYWOMAN && m_animGroup != ASSOCGRP_WOMAN) + canUseMyBody = true; + } + if(canUseMyBody) + m_pedIK.m_flags &= ~CPedIK::LOOKAROUND_HEAD_ONLY; } } @@ -11071,7 +11344,7 @@ CPed::PointGunAt(void) CAnimBlendAssociation *weaponAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_WEAPON_FIRE); if (!weaponAssoc || weaponAssoc->blendDelta < 0.0f) { if (!!weaponInfo->m_bCrouchFire) { - weaponAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_WEAPON_CROUCHFIRE); + weaponAssoc = RpAnimBlendClumpGetAssociation(GetClump(), GetCrouchFireAnim(weaponInfo)); animLoopStart = weaponInfo->m_fAnim2LoopStart; } } @@ -11374,7 +11647,7 @@ CPed::SetJump(void) #ifdef VC_PED_PORTS m_nPedState != PED_JUMP && !RpAnimBlendClumpGetAssociation(GetClump(), ANIM_JUMP_LAUNCH) && #endif - (m_nSurfaceTouched != SURFACE_STONE || DotProduct(GetForward(), m_vecDamageNormal) >= 0.0f)) { + (m_nSurfaceTouched != SURFACE_STEEP_CLIFF || DotProduct(GetForward(), m_vecDamageNormal) >= 0.0f)) { SetStoredState(); m_nPedState = PED_JUMP; CAnimBlendAssociation *jumpAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_JUMP_LAUNCH, 8.0f); @@ -12143,19 +12416,7 @@ CPed::PedSetInCarCB(CAnimBlendAssociation *animAssoc, void *arg) ped->SetObjective(OBJECTIVE_NONE); } - if (veh->pDriver == ped) { - if (veh->bLowVehicle) { - ped->m_pVehicleAnim = CAnimManager::BlendAnimation(ped->GetClump(), ASSOCGRP_STD, ANIM_CAR_LSIT, 100.0f); - } else { - ped->m_pVehicleAnim = CAnimManager::BlendAnimation(ped->GetClump(), ASSOCGRP_STD, ANIM_CAR_SIT, 100.0f); - } - } else if (veh->bLowVehicle) { - ped->m_pVehicleAnim = CAnimManager::BlendAnimation(ped->GetClump(), ASSOCGRP_STD, ANIM_CAR_SITPLO, 100.0f); - } else { - ped->m_pVehicleAnim = CAnimManager::BlendAnimation(ped->GetClump(), ASSOCGRP_STD, ANIM_CAR_SITP, 100.0f); - } - - ped->StopNonPartialAnims(); + ped->AddInCarAnims(veh, veh->pDriver == ped); if (veh->bIsBus) ped->bRenderPedInCar = false; @@ -12544,7 +12805,7 @@ CPed::PedSetOutCarCB(CAnimBlendAssociation *animAssoc, void *arg) } // --MIAMI: Done, but enumarate weapon slots -inline void +void CPed::ReplaceWeaponWhenExitingVehicle(void) { eWeaponType weaponType = GetWeapon()->m_eWeaponType; @@ -12560,11 +12821,11 @@ CPed::ReplaceWeaponWhenExitingVehicle(void) } } -// --MIAMI: Add driveby check, enumarate weapon slots -inline void +// --MIAMI: Done +void CPed::RemoveWeaponWhenEnteringVehicle(void) { - if (IsPlayer() && GetWeapon(5).m_eWeaponType && GetWeapon(5).m_nAmmoTotal > 0) { + if (IsPlayer() && HasWeaponSlot(5) && GetWeapon(5).m_nAmmoTotal > 0 && ((CPlayerPed*)this)->GetPlayerInfoForThisPlayerPed()->m_bDriveByAllowed) { if (m_storedWeapon == WEAPONTYPE_UNIDENTIFIED) m_storedWeapon = GetWeapon()->m_eWeaponType; SetCurrentWeapon(GetWeapon(5).m_eWeaponType); @@ -13015,14 +13276,26 @@ CPed::ProcessObjective(void) case OBJECTIVE_FOLLOW_CAR_IN_CAR: case OBJECTIVE_FIRE_AT_OBJ_FROM_VEHICLE: case OBJECTIVE_DESTROY_OBJ: - case OBJECTIVE_23: - case OBJECTIVE_24: + case OBJECTIVE_26: + case OBJECTIVE_27: case OBJECTIVE_SET_LEADER: break; case OBJECTIVE_IDLE: - SetIdle(); - m_objective = OBJECTIVE_NONE; - SetMoveState(PEDMOVE_STILL); + if (GetPedState() == PED_DRIVING) + m_objective = OBJECTIVE_NONE; + else { + SetIdle(); + if (m_attractor) { + if (m_objectiveTimer && CTimer::GetTimeInMilliseconds() > m_nWaitTimer) { + GetPedAttractorManager()->BroadcastDeparture(this, m_attractor); + m_objectiveTimer = 0; + } + } + else { + m_objective = OBJECTIVE_NONE; + SetMoveState(PEDMOVE_STILL); + } + } break; case OBJECTIVE_FLEE_TILL_SAFE: if (InVehicle()) { @@ -13100,7 +13373,8 @@ CPed::ProcessObjective(void) } else { bool targetHasVeh = m_pedInObjective->bInVehicle; if (!targetHasVeh - || targetHasVeh && m_pedInObjective->m_pMyVehicle->CanPedExitCar()) { +// TODO(MIAMI): argument + || targetHasVeh && m_pedInObjective->m_pMyVehicle->CanPedExitCar(false)) { m_pMyVehicle->AutoPilot.m_nCruiseSpeed = 0; m_pMyVehicle->AutoPilot.m_nCarMission = MISSION_NONE; SetObjective(OBJECTIVE_LEAVE_VEHICLE, m_pMyVehicle); @@ -13403,7 +13677,7 @@ CPed::ProcessObjective(void) CVector target; CVector ourHead = GetMatrix() * CVector(0.5f, 0.0f, 0.6f); if (m_pedInObjective->IsPed()) - m_pedInObjective->m_pedIK.GetComponentPosition((RwV3d*)&target, PED_MID); + m_pedInObjective->m_pedIK.GetComponentPosition(*(RwV3d *)&target, PED_MID); else target = m_pedInObjective->GetPosition(); @@ -14087,7 +14361,7 @@ CPed::ProcessObjective(void) if (reloadAssoc || !m_pedInObjective->IsPedShootable()) { if (reloadAssoc && - (!reloadAssoc->IsRunning() || reloadAssoc->currentTime / reloadAssoc->hierarchy->totalLength > 0.8f)) { + (!reloadAssoc->IsRunning() || reloadAssoc->GetProgress() > 0.8f)) { CAnimBlendAssociation *punchAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_FIGHT_PPUNCH, 8.0f); punchAssoc->flags |= ASSOC_DELETEFADEDOUT; punchAssoc->flags |= ASSOC_FADEOUTWHENDONE; @@ -14201,6 +14475,187 @@ CPed::ProcessObjective(void) } break; } + case OBJECTIVE_USE_SEAT_ATTRACTOR: + case OBJECTIVE_USE_ATM_ATTRACTOR: + case OBJECTIVE_USE_STOP_ATTRACTOR: + case OBJECTIVE_USE_PIZZA_ATTRACTOR: + case OBJECTIVE_USE_SHELTER_ATTRACTOR: + case OBJECTIVE_USE_ICECREAM_ATTRACTOR: + if (CTimer::GetTimeInMilliseconds() > m_objectiveTimer) { + m_objectiveTimer = 0; + if (m_attractor) + GetPedAttractorManager()->DeRegisterPed(this, m_attractor); + } + else { + CVector distance = m_nextRoutePointPos - GetPosition(); + distance.z = 0.0f; + if (m_objective == OBJECTIVE_USE_SHELTER_ATTRACTOR) { + if (m_nMoveState == PEDMOVE_SPRINT && distance.Magnitude() < SQR(2.0f)) { + SetMoveState(PEDMOVE_WALK); + bIsRunning = false; + } + else if (CWeather::Rain < 0.2f && m_attractor) { + GetPedAttractorManager()->DeRegisterPed(this, m_attractor); + return; + } + } + else if (m_objective == OBJECTIVE_USE_ICECREAM_ATTRACTOR) { + if (m_nMoveState == PEDMOVE_SPRINT && distance.Magnitude() < SQR(4.0f)) { + SetMoveState(PEDMOVE_WALK); + bIsRunning = false; + } + CVehicle* pIceCreamVan = GetPedAttractorManager()->GetIceCreamVanForEffect(m_attractor->GetEffect()); + if (0.01f * CTimer::GetTimeStep() * 5.0f < pIceCreamVan->m_fDistanceTravelled) { + GetPedAttractorManager()->DeRegisterPed(this, m_attractor); + return; + } + if (!pIceCreamVan->pDriver || + !pIceCreamVan->pDriver->IsPlayer() || + pIceCreamVan->pDriver->GetPedState() == PED_ARRESTED || + pIceCreamVan->pDriver->GetPedState() == PED_DEAD) { + GetPedAttractorManager()->DeRegisterPed(this, m_attractor); + return; + } + if (!pIceCreamVan->m_bSirenOrAlarm) { + GetPedAttractorManager()->DeRegisterPed(this, m_attractor); + return; + } + if (pIceCreamVan->GetStatus() == STATUS_WRECKED) { + GetPedAttractorManager()->DeRegisterPed(this, m_attractor); + return; + } + } + if (sq(m_distanceToCountSeekDone) < distance.MagnitudeSqr()) { + if (CTimer::GetTimeInMilliseconds() > m_nPedStateTimer || GetPedState() != PED_SEEK_POS) + SetSeek(m_vecSeekPos, m_distanceToCountSeekDone); + } + else { + if (!bReachedAttractorHeadingTarget) { + float fHeadingDistance = m_fRotationCur - m_attractorHeading; + float fSinHeading = Sin(fHeadingDistance); + float fCosHeading = Cos(fHeadingDistance); + if (fSinHeading > 0.0f) { + if (fCosHeading > 0.0f) + m_attractorHeading = m_fRotationCur - Asin(fSinHeading); + else + m_attractorHeading = m_fRotationCur - Acos(fCosHeading); + } + else { + if (fCosHeading > 0.0f) + m_attractorHeading = m_fRotationCur - Asin(fSinHeading); + else + m_attractorHeading = m_fRotationCur + Acos(fCosHeading); + } + m_fRotationDest = m_attractorHeading; + m_headingRate = 3.5f; + bReachedAttractorHeadingTarget = true; + bTurnedAroundOnAttractor = false; + } + if (Abs(m_fRotationCur - m_attractorHeading) >= m_acceptableHeadingOffset && + Abs(m_fRotationCur - m_attractorHeading + TWOPI) >= m_acceptableHeadingOffset && + Abs(m_fRotationCur - m_attractorHeading - TWOPI) >= m_acceptableHeadingOffset) + SetMoveState(PEDMOVE_STILL); + else { + m_fRotationDest = m_fRotationCur; + bReachedAttractorHeadingTarget = false; + bObjectiveCompleted = true; + bScriptObjectiveCompleted = true; + RestoreHeadingRate(); + GetPedAttractorManager()->BroadcastArrival(this, m_attractor); + if (GetPedAttractorManager()->IsAtHeadOfQueue(this, m_attractor)) { + switch (m_objective) { + case OBJECTIVE_USE_SEAT_ATTRACTOR: + if (!bTurnedAroundOnAttractor) { + ClearObjective(); + SetWaitState(WAITSTATE_SIT_DOWN, 0); + } + else { + ClearObjective(); + SetWaitState(WAITSTATE_SIT_DOWN_RVRS, 0); + } + break; + case OBJECTIVE_USE_ATM_ATTRACTOR: + ClearObjective(); + SetWaitState(WAITSTATE_USE_ATM, 0); + break; + case OBJECTIVE_USE_STOP_ATTRACTOR: + ClearObjective(); + SetObjective(OBJECTIVE_WAIT_FOR_BUS); + break; + case OBJECTIVE_USE_PIZZA_ATTRACTOR: + ClearObjective(); + m_prevObjective = OBJECTIVE_NONE; + SetObjective(OBJECTIVE_IDLE); + m_objectiveTimer = CTimer::GetTimeInMilliseconds() + m_attractor->GetHeadOfQueueWaitTime(); + break; + case OBJECTIVE_USE_SHELTER_ATTRACTOR: + m_prevObjective = OBJECTIVE_NONE; + SetObjective(OBJECTIVE_WAIT_FOR_RAIN_TO_END); + break; + case OBJECTIVE_USE_ICECREAM_ATTRACTOR: + m_prevObjective = OBJECTIVE_NONE; + SetObjective(OBJECTIVE_PURCHASE_ICECREAM); + break; + } + } + } + } + } + return; + case OBJECTIVE_WAIT_FOR_RAIN_TO_END: + SetIdle(); + if (m_attractor && CWeather::Rain < 0.2f) + GetPedAttractorManager()->DeRegisterPed(this, m_attractor); + break; + case OBJECTIVE_WAIT_FOR_BUS: + SetIdle(); + if (m_attractor) { + float left = GetPosition().x - 10.0f; + float right = GetPosition().x + 10.0f; + float top = GetPosition().y - 10.0f; + float bottom = GetPosition().y + 10.0f; + int xstart = Max(0, CWorld::GetSectorIndexX(left)); + int xend = Min(NUMSECTORS_X - 1, CWorld::GetSectorIndexX(right)); + int ystart = Max(0, CWorld::GetSectorIndexY(top)); + int yend = Min(NUMSECTORS_Y - 1, CWorld::GetSectorIndexY(bottom)); + assert(xstart <= xend); + assert(ystart <= yend); + + float minDistance = SQR(10.0f); + CVehicle* pBus = nil; + + for (int y = ystart; y <= yend; y++) { + for (int x = xstart; x <= xend; x++) { + CSector* s = CWorld::GetSector(x, y); + for (CPtrNode* pNode = s->m_lists[ENTITYLIST_VEHICLES].first; pNode != nil; pNode = pNode->next) { + CEntity* pEntity = (CEntity*)pNode->item; + if (!pEntity->IsVehicle()) + continue; + CVehicle* pVehicle = (CVehicle*)pEntity; + if (!pVehicle->bIsBus) + continue; + if (pVehicle->GetMoveSpeed().MagnitudeSqr() >= SQR(0.005f)) + continue; + float distanceSq = (GetPosition() - pVehicle->GetPosition()).MagnitudeSqr(); + if (distanceSq < minDistance) { + minDistance = distanceSq; + pBus = pVehicle; + } + } + } + } + + if (pBus) { + if (pBus->m_nNumPassengers >= pBus->m_nNumMaxPassengers - 1) + SetObjective(OBJECTIVE_IDLE); + else { + GetPedAttractorManager()->DeRegisterPed(this, m_attractor); + SetObjective(OBJECTIVE_ENTER_CAR_AS_PASSENGER, pBus); + bDontDragMeOutCar = true; // TODO(MIAMI): check, add more flags + } + } + } + break; #endif } if (bObjectiveCompleted @@ -14931,10 +15386,10 @@ CPed::ProcessEntityCollision(CEntity *collidingEnt, CColPoint *collidingPoints) if (CCollision::IsStoredPolyStillValidVerticalLine(pos, potentialGroundZ, intersectionPoint, &m_collPoly)) { bStillOnValidPoly = true; #ifdef VC_PED_PORTS - if(!bSomeVCflag1 || FEET_OFFSET + intersectionPoint.point.z < GetPosition().z) { + if(!bHeadStuckInCollision || FEET_OFFSET + intersectionPoint.point.z < GetPosition().z) { GetMatrix().GetPosition().z = FEET_OFFSET + intersectionPoint.point.z; - if (bSomeVCflag1) - bSomeVCflag1 = false; + if (bHeadStuckInCollision) + bHeadStuckInCollision = false; } #else GetMatrix().GetPosition().z = FEET_OFFSET + intersectionPoint.point.z; @@ -14974,13 +15429,13 @@ CPed::ProcessEntityCollision(CEntity *collidingEnt, CColPoint *collidingPoints) } float minDist = 1.0f; belowTorsoCollided = CCollision::ProcessVerticalLine(ourLine, collidingEnt->GetMatrix(), *hisCol, - intersectionPoint, minDist, false, &m_collPoly); + intersectionPoint, minDist, false, false, &m_collPoly); if (collidedWithBoat && bWasStanding && !belowTorsoCollided) { ourLine.p0.z = ourLine.p1.z; ourLine.p1.z = ourLine.p1.z + gravityEffect; belowTorsoCollided = CCollision::ProcessVerticalLine(ourLine, collidingEnt->GetMatrix(), *hisCol, - intersectionPoint, minDist, false, &m_collPoly); + intersectionPoint, minDist, false, false, &m_collPoly); } if (belowTorsoCollided) { #ifndef VC_PED_PORTS @@ -15009,16 +15464,16 @@ CPed::ProcessEntityCollision(CEntity *collidingEnt, CColPoint *collidingPoints) } } #ifdef VC_PED_PORTS - if (!bSomeVCflag1 || FEET_OFFSET + intersectionPoint.point.z < GetPosition().z) { + if (!bHeadStuckInCollision || FEET_OFFSET + intersectionPoint.point.z < GetPosition().z) { GetMatrix().GetPosition().z = FEET_OFFSET + intersectionPoint.point.z; - if (bSomeVCflag1) - bSomeVCflag1 = false; + if (bHeadStuckInCollision) + bHeadStuckInCollision = false; } #else GetMatrix().GetPosition().z = FEET_OFFSET + intersectionPoint.point.z; #endif m_nSurfaceTouched = intersectionPoint.surfaceB; - if (m_nSurfaceTouched == SURFACE_STONE) { + if (m_nSurfaceTouched == SURFACE_STEEP_CLIFF) { bHitSteepSlope = true; m_vecDamageNormal = intersectionPoint.normal; } @@ -15099,12 +15554,12 @@ CPed::ProcessEntityCollision(CEntity *collidingEnt, CColPoint *collidingPoints) sphereNormal.x = -m_vecMoveSpeed.x / Max(0.001f, speed); sphereNormal.y = -m_vecMoveSpeed.y / Max(0.001f, speed); GetMatrix().GetPosition().z -= 0.05f; - bSomeVCflag1 = true; + bHeadStuckInCollision = true; } #endif sphereNormal.Normalise(); collidingPoints[sphere].normal = sphereNormal; - if (collidingPoints[sphere].surfaceB == SURFACE_STONE) + if (collidingPoints[sphere].surfaceB == SURFACE_STEEP_CLIFF) bHitSteepSlope = true; } } @@ -15218,19 +15673,22 @@ CPed::SetEnterTrain(CVehicle *train, uint32 unused) } #endif +// --MIAMI: Done, but what is this parameter for? void -CPed::SetDuck(uint32 time) +CPed::SetDuck(uint32 time, bool sth) { - if (bIsDucking || CTimer::GetTimeInMilliseconds() <= m_duckTimer) - return; - - if (bCrouchWhenShooting && (m_nPedState == PED_ATTACK || m_nPedState == PED_AIM_GUN)) { - CAnimBlendAssociation *duckAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_DUCK_LOW); - if (!duckAssoc || duckAssoc->blendDelta < 0.0f) { - CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_DUCK_LOW, 4.0f); - bIsDucking = true; + if (bIsDucking || CTimer::GetTimeInMilliseconds() <= m_duckTimer && !sth) { + if (sth && CTimer::GetTimeInMilliseconds() + time > m_duckTimer) m_duckTimer = CTimer::GetTimeInMilliseconds() + time; - } + return; + } + + CAnimBlendAssociation *duckAssoc; + if (bCrouchWhenShooting) { + duckAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_WEAPON_CROUCH, 4.0f); + duckAssoc->flags &= ~ASSOC_FADEOUTWHENDONE; + bIsDucking = true; + m_duckTimer = CTimer::GetTimeInMilliseconds() + time; } else { CAnimBlendAssociation *duckAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_DUCK_DOWN); if (!duckAssoc || duckAssoc->blendDelta < 0.0f) { @@ -15518,6 +15976,7 @@ CPed::ProcessBuoyancy(void) m_vecMoveSpeed.y *= speedMult; m_vecMoveSpeed.z *= speedMult; bIsStanding = false; + bIsDrowning = true; InflictDamage(nil, WEAPONTYPE_DROWNING, 3.0f * CTimer::GetTimeStep(), PEDPIECE_TORSO, 0); } if (buoyancyImpulse.z / m_fMass > 0.002f * CTimer::GetTimeStep()) { @@ -15630,8 +16089,9 @@ CPed::SetSolicit(uint32 time) } bool -CPed::SetFollowPath(CVector dest) +CPed::SetFollowPath(CVector dest, float radius, eMoveState state, CEntity* pFollowedPed, CEntity*, int time) { + // TODO(MIAMI): new follow if (m_nPedState == PED_FOLLOW_PATH) return false; @@ -15693,7 +16153,8 @@ CPed::SetExitCar(CVehicle *veh, uint32 wantedDoorNode) uint32 optedDoorNode = wantedDoorNode; bool teleportNeeded = false; bool isLow = !!veh->bLowVehicle; - if (!veh->CanPedExitCar()) { +// TODO(MIAMI): argument + if (!veh->CanPedExitCar(false)) { if (veh->pDriver && !veh->pDriver->IsPlayer()) { veh->AutoPilot.m_nCruiseSpeed = 0; veh->AutoPilot.m_nCarMission = MISSION_NONE; @@ -16503,7 +16964,7 @@ CPed::ServiceTalking(void) } else { m_queuedSound = SOUND_PED_BOMBER; } - if (m_queuedSound != SOUND_TOTAL_PED_SOUNDS) { + if (m_queuedSound != SOUND_NO_SOUND) { if (m_queuedSound == SOUND_PED_DEATH) m_soundStart = CTimer::GetTimeInMilliseconds() - 1; @@ -16515,7 +16976,7 @@ CPed::ServiceTalking(void) + CTimer::GetTimeInMilliseconds() + CGeneral::GetRandomNumberInRange(0, CommentWaitTime[m_queuedSound - SOUND_PED_DEATH].m_nOverrideFixedDelayTime); m_lastQueuedSound = m_queuedSound; - m_queuedSound = SOUND_TOTAL_PED_SOUNDS; + m_queuedSound = SOUND_NO_SOUND; } } } @@ -16969,7 +17430,7 @@ CPed::UpdatePosition(void) velocityChange = m_moved + velocityOfSurface - m_vecMoveSpeed; m_fRotationCur += curSurface->m_vecTurnSpeed.z * CTimer::GetTimeStep(); m_fRotationDest += curSurface->m_vecTurnSpeed.z * CTimer::GetTimeStep(); - } else if (m_nSurfaceTouched != SURFACE_STONE || m_vecDamageNormal.x == 0.0f && m_vecDamageNormal.y == 0.0f) { + } else if (m_nSurfaceTouched != SURFACE_STEEP_CLIFF || m_vecDamageNormal.x == 0.0f && m_vecDamageNormal.y == 0.0f) { velocityChange = m_moved - m_vecMoveSpeed; } else { // Ped got damaged by steep slope @@ -17245,39 +17706,33 @@ CPed::WarpPedIntoCar(CVehicle *car) DMAudio.PlayOneShot(car->m_audioEntityId, SOUND_CAR_ENGINE_START, 1.0f); } -#ifdef VC_PED_PORTS RpAnimBlendClumpSetBlendDeltas(GetClump(), ASSOC_PARTIAL, -1000.0f); - // VC uses AddInCarAnims but we don't have that - m_pVehicleAnim = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, car->GetDriverAnim(), 100.0f); + AddInCarAnims(car, car->pDriver == this); RemoveWeaponWhenEnteringVehicle(); -#else - if (car->IsBoat()) { -#ifndef FIX_BUGS - m_pVehicleAnim = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_DRIVE_BOAT, 100.0f); -#else - m_pVehicleAnim = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, car->GetDriverAnim(), 100.0f); -#endif - CWeaponInfo *ourWeapon = CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType); - RemoveWeaponModel(ourWeapon->m_nModelId); - } else { - // Because we can use Uzi for drive by - RemoveWeaponWhenEnteringVehicle(); - if (car->bLowVehicle) - m_pVehicleAnim = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_CAR_LSIT, 100.0f); - else - m_pVehicleAnim = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_CAR_SIT, 100.0f); - } -#endif - - StopNonPartialAnims(); if (car->bIsBus) bRenderPedInCar = false; bChangedSeat = true; } +void +CPed::SetObjective(eObjective newObj, float heading, const CVector& pos) +{ + switch (newObj) { + case OBJECTIVE_USE_SEAT_ATTRACTOR: + case OBJECTIVE_USE_ATM_ATTRACTOR: + case OBJECTIVE_USE_STOP_ATTRACTOR: + case OBJECTIVE_USE_PIZZA_ATTRACTOR: + case OBJECTIVE_USE_SHELTER_ATTRACTOR: + case OBJECTIVE_USE_ICECREAM_ATTRACTOR: + ClearPointGunAt(); + SetObjective(newObj, pos); + m_attractorHeading = heading; + } +} + void CPed::SetObjective(eObjective newObj, CVector dest) { @@ -17327,14 +17782,50 @@ CPed::SetObjective(eObjective newObj, CVector dest) break; case OBJECTIVE_GOTO_AREA_ANY_MEANS: case OBJECTIVE_GOTO_AREA_ON_FOOT: + case OBJECTIVE_USE_SEAT_ATTRACTOR: + case OBJECTIVE_USE_ATM_ATTRACTOR: + case OBJECTIVE_USE_STOP_ATTRACTOR: + case OBJECTIVE_USE_PIZZA_ATTRACTOR: + case OBJECTIVE_USE_SHELTER_ATTRACTOR: + case OBJECTIVE_USE_ICECREAM_ATTRACTOR: bIsRunning = false; m_pNextPathNode = nil; m_nextRoutePointPos = dest; m_vecSeekPos = m_nextRoutePointPos; m_distanceToCountSeekDone = 0.5f; - bUsePedNodeSeek = true; - if (sq(m_distanceToCountSeekDone) > (m_nextRoutePointPos - GetPosition()).MagnitudeSqr2D()) - return; + if (m_objective == OBJECTIVE_USE_ATM_ATTRACTOR) { + m_distanceToCountSeekDone = m_attractor->GetDistanceToCountSeekDone(); + m_acceptableHeadingOffset = m_attractor->GetAcceptableHeading(); + } + if (m_objective == OBJECTIVE_USE_SEAT_ATTRACTOR) { + m_distanceToCountSeekDone = m_attractor->GetDistanceToCountSeekDone(); + m_acceptableHeadingOffset = m_attractor->GetAcceptableHeading(); + } + if (m_objective == OBJECTIVE_USE_STOP_ATTRACTOR) { + m_distanceToCountSeekDone = m_attractor->GetDistanceToCountSeekDone(); + m_acceptableHeadingOffset = m_attractor->GetAcceptableHeading(); + } + if (m_objective == OBJECTIVE_USE_PIZZA_ATTRACTOR) { + m_distanceToCountSeekDone = m_attractor->GetDistanceToCountSeekDone(); + m_acceptableHeadingOffset = m_attractor->GetAcceptableHeading(); + } + if (m_objective == OBJECTIVE_USE_SHELTER_ATTRACTOR) { + bIsRunning = true; + m_distanceToCountSeekDone = m_attractor->GetDistanceToCountSeekDone(); + m_acceptableHeadingOffset = m_attractor->GetAcceptableHeading(); + } + if (m_objective == OBJECTIVE_USE_ICECREAM_ATTRACTOR) { + bIsRunning = true; + m_distanceToCountSeekDone = m_attractor->GetDistanceToCountSeekDone(); + m_acceptableHeadingOffset = m_attractor->GetAcceptableHeading(); + } + bUsePedNodeSeek = false; + if (sq(m_distanceToCountSeekDone) > (m_nextRoutePointPos - GetPosition()).MagnitudeSqr2D()) { + if (!IsUseAttractorObjective(m_objective)) + return; + if (Abs(m_fRotationCur - m_attractorHeading) < m_acceptableHeadingOffset) + return; + } break; case OBJECTIVE_RUN_TO_AREA: bIsRunning = true; @@ -17501,25 +17992,13 @@ CPed::SetEnterCar_AllClear(CVehicle *car, uint32 doorNode, uint32 doorFlag) m_vecOffsetSeek = doorOpenPos - GetPosition(); m_nPedStateTimer = CTimer::GetTimeInMilliseconds() + 600; if (car->IsBoat()) { -#ifdef VC_PED_PORTS - // VC checks for handling flag, but we can't do that - if(car->GetModelIndex() == MI_SPEEDER) + if(car->pHandling->Flags & HANDLING_SIT_IN_BOAT) m_pVehicleAnim = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_CAR_SIT, 100.0f); else m_pVehicleAnim = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_DRIVE_BOAT, 100.0f); PedSetInCarCB(nil, this); bVehExitWillBeInstant = true; -#else - -#ifndef FIX_BUGS - m_pVehicleAnim = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_DRIVE_BOAT, 100.0f); -#else - m_pVehicleAnim = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, car->GetDriverAnim(), 100.0f); -#endif - - m_pVehicleAnim->SetFinishCallback(PedSetInCarCB, this); -#endif if (IsPlayer()) CWaterLevel::AllocateBoatWakeArray(); } else { @@ -17961,6 +18440,65 @@ CPed::SetExitBoat(CVehicle *boat) CWaterLevel::FreeBoatWakeArray(); } +void +CPed::SetNewAttraction(CPedAttractor* pAttractor, const CVector& pos, float heading, float time, int32 qid) +{ + if (!m_attractor) + m_attractor = pAttractor; + if (m_attractor != pAttractor) + return; + switch (pAttractor->GetEffect()->pedattr.type) { + case ATTRACTOR_ATM: SetObjective(OBJECTIVE_USE_ATM_ATTRACTOR, heading, pos); break; + case ATTRACTOR_SEAT: SetObjective(OBJECTIVE_USE_SEAT_ATTRACTOR, heading, pos); break; + case ATTRACTOR_STOP: SetObjective(OBJECTIVE_USE_STOP_ATTRACTOR, heading, pos); break; + case ATTRACTOR_PIZZA: SetObjective(OBJECTIVE_USE_PIZZA_ATTRACTOR, heading, pos); break; + case ATTRACTOR_SHELTER: SetObjective(OBJECTIVE_USE_SHELTER_ATTRACTOR, heading, pos); break; + case ATTRACTOR_ICECREAM: SetObjective(OBJECTIVE_USE_ICECREAM_ATTRACTOR, heading, pos); break; + default: return; + } + SetObjectiveTimer(time); + m_positionInQueue = qid; +} + +void +CPed::ClearWaitState(void) +{ + switch (m_nWaitState) { + case WAITSTATE_PLAYANIM_CHAT: + case WAITSTATE_SIT_DOWN: + case WAITSTATE_SIT_DOWN_RVRS: + case WAITSTATE_SIT_UP: + case WAITSTATE_SIT_IDLE: + case WAITSTATE_USE_ATM: + if (CTimer::GetTimeInMilliseconds() <= m_nWaitTimer) { + AnimationId id; + switch (m_nWaitState) { // TODO(MIAMI): actual! + case WAITSTATE_PLAYANIM_CHAT: id = ANIM_IDLE_CHAT; break; + case WAITSTATE_SIT_DOWN: id = ANIM_SEAT_DOWN; break; + case WAITSTATE_SIT_DOWN_RVRS: id = ANIM_SEAT_DOWN2; break; + case WAITSTATE_SIT_UP: id = ANIM_SEAT_UP; break; + case WAITSTATE_SIT_IDLE: id = ANIM_SEAT_IDLE; break; + case WAITSTATE_USE_ATM: id = ANIM_ATM; break; + } + CAnimBlendAssociation* pAssoc = RpAnimBlendClumpGetAssociation(GetClump(), id); + if (pAssoc) + pAssoc->blendDelta = -8.0f; + if (m_attractor) + GetPedAttractorManager()->DeRegisterPed(this, m_attractor); + } + break; + case WAITSTATE_RIOT: + case WAITSTATE_FAST_FALL: + case WAITSTATE_BOMBER: + case WAITSTATE_STRIPPER: + case WAITSTATE_GROUND_ATTACK: + case WAITSTATE_LANCESITTING: + case WAITSTATE_PLAYANIM_HANDSUP_SIMPLE: + assert(0); + } + m_nWaitState = WAITSTATE_FALSE; +} + #ifdef COMPATIBLE_SAVES #define CopyFromBuf(buf, data) memcpy(&data, buf, sizeof(data)); SkipSaveBuf(buf, sizeof(data)); #define CopyToBuf(buf, data) memcpy(buf, &data, sizeof(data)); SkipSaveBuf(buf, sizeof(data)); @@ -17977,7 +18515,7 @@ CPed::Save(uint8*& buf) CopyToBuf(buf, m_fHealth); CopyToBuf(buf, m_fArmour); SkipSaveBuf(buf, 148); - for (int i = 0; i < 10; i++) // has to be hardcoded + for (int i = 0; i < 13; i++) // has to be hardcoded m_weapons[i].Save(buf); SkipSaveBuf(buf, 5); CopyToBuf(buf, m_maxWeaponTypeAllowed); @@ -17999,8 +18537,10 @@ CPed::Load(uint8*& buf) SkipSaveBuf(buf, 148); CWeapon bufWeapon; - for (int i = 0; i < 10; i++) { // has to be hardcoded + for (int i = 0; i < 13; i++) { // has to be hardcoded bufWeapon.Load(buf); + if (i >= 10) + continue; // tmp hack before we fix save/load if (bufWeapon.m_eWeaponType != WEAPONTYPE_UNARMED) { int modelId = CWeaponInfo::GetWeaponInfo(bufWeapon.m_eWeaponType)->m_nModelId; @@ -18023,14 +18563,15 @@ CPed::Load(uint8*& buf) #undef CopyToBuf #endif +// --MIAMI: Done void CPed::GiveDelayedWeapon(eWeaponType weapon, uint32 ammo) { - m_storedWeapon = weapon; - m_storedWeaponAmmo = ammo; - if (m_storedWeapon != WEAPONTYPE_UNIDENTIFIED) { - int modelId1 = CWeaponInfo::GetWeaponInfo(m_storedWeapon)->m_nModelId; - int modelId2 = CWeaponInfo::GetWeaponInfo(m_storedWeapon)->m_nModel2Id; + m_delayedWeapon = weapon; + m_delayedWeaponAmmo = ammo; + if (m_delayedWeapon != WEAPONTYPE_UNIDENTIFIED) { + int modelId1 = CWeaponInfo::GetWeaponInfo(m_delayedWeapon)->m_nModelId; + int modelId2 = CWeaponInfo::GetWeaponInfo(m_delayedWeapon)->m_nModel2Id; if (modelId1 != -1) CStreaming::RequestModel(modelId1, STREAMFLAGS_DEPENDENCY); if (modelId2 != -1) @@ -18038,18 +18579,19 @@ CPed::GiveDelayedWeapon(eWeaponType weapon, uint32 ammo) if ((modelId1 == -1 || CStreaming::HasModelLoaded(modelId1)) && (modelId2 == -1 || CStreaming::HasModelLoaded(modelId2))) { - GiveWeapon(m_storedWeapon, m_storedWeaponAmmo, 1); - m_storedWeapon = WEAPONTYPE_UNIDENTIFIED; + GiveWeapon(m_delayedWeapon, m_delayedWeaponAmmo, true); + m_delayedWeapon = WEAPONTYPE_UNIDENTIFIED; } } } +// --MIAMI: Done void CPed::RequestDelayedWeapon() { - if (m_storedWeapon != WEAPONTYPE_UNIDENTIFIED) { - int modelId1 = CWeaponInfo::GetWeaponInfo(m_storedWeapon)->m_nModelId; - int modelId2 = CWeaponInfo::GetWeaponInfo(m_storedWeapon)->m_nModel2Id; + if (m_delayedWeapon != WEAPONTYPE_UNIDENTIFIED) { + int modelId1 = CWeaponInfo::GetWeaponInfo(m_delayedWeapon)->m_nModelId; + int modelId2 = CWeaponInfo::GetWeaponInfo(m_delayedWeapon)->m_nModel2Id; if (modelId1 != -1) CStreaming::RequestModel(modelId1, STREAMFLAGS_DEPENDENCY); if (modelId2 != -1) @@ -18057,12 +18599,13 @@ CPed::RequestDelayedWeapon() if ((modelId1 == -1 || CStreaming::HasModelLoaded(modelId1)) && (modelId2 == -1 || CStreaming::HasModelLoaded(modelId2))) { - GiveWeapon(m_storedWeapon, m_storedWeaponAmmo, 1); - m_storedWeapon = WEAPONTYPE_UNIDENTIFIED; + GiveWeapon(m_delayedWeapon, m_delayedWeaponAmmo, 1); + m_delayedWeapon = WEAPONTYPE_UNIDENTIFIED; } } } +// --MIAMI: Done void CPed::ClearFollowPath() { @@ -18071,4 +18614,75 @@ CPed::ClearFollowPath() } m_nPathNodes = 0; m_nCurPathNode = 0; -} \ No newline at end of file +} + +// --MIAMI: Done except bikes +void +CPed::AddInCarAnims(CVehicle* car, bool isDriver) +{ + AnimationId anim; + AssocGroupId group; + if (car->IsBoat()) { + if (car->pHandling->Flags & HANDLING_SIT_IN_BOAT) { + anim = ANIM_CAR_SIT; + } else { + anim = ANIM_DRIVE_BOAT; + } + group = ASSOCGRP_STD; + } else if (car->IsBike()) { + if (isDriver) { + // TODO(Miami): Bikes + } else { + // TODO(Miami): Bikes + } + } else { + if (isDriver) { + if (car->bLowVehicle) { + anim = ANIM_CAR_LSIT; + } else { + anim = ANIM_CAR_SIT; + } + } else { + if (car->bLowVehicle) { + anim = ANIM_CAR_SITPLO; + } else { + anim = ANIM_CAR_SITP; + } + } + group = ASSOCGRP_STD; + } + m_pVehicleAnim = CAnimManager::BlendAnimation(GetClump(), group, anim, 100.0f); + + StopNonPartialAnims(); +} + +bool +CPed::CanBeDamagedByThisGangMember(CPed* who) +{ + return m_gangFlags & (1 << (uint8)(who->m_nPedType - PEDTYPE_GANG1)); +} + +bool +IsPedPointerValid_NotInWorld(CPed* pPed) +{ + if (!pPed) + return false; + int index = CPools::GetPedPool()->GetJustIndex(pPed); +#ifdef FIX_BUGS + if (index < 0 || index >= NUMPEDS) +#else + if (index < 0 || index > NUMPEDS) +#endif + return false; + return true; +} + +bool +IsPedPointerValid(CPed* pPed) +{ + if (!IsPedPointerValid_NotInWorld(pPed)) + return false; + if (pPed->bInVehicle && pPed->m_pMyVehicle) + return IsEntityPointerValid(pPed->m_pMyVehicle); + return pPed->m_entryInfoList.first || pPed == FindPlayerPed(); +} diff --git a/src/peds/Ped.h b/src/peds/Ped.h index 4ad74b15..155e6cea 100644 --- a/src/peds/Ped.h +++ b/src/peds/Ped.h @@ -19,6 +19,7 @@ class CObject; class CFire; struct AnimBlendFrameData; class CAnimBlendAssociation; +class CPedAttractor; struct PedAudioData { @@ -78,11 +79,11 @@ struct FightMove float endFireTime; float comboFollowOnTime; float strikeRadius; + float extendReachMultiplier; uint8 hitLevel; // FightMoveHitLevel uint8 damage; uint8 flags; }; -VALIDATE_SIZE(FightMove, 0x18); // TODO: This is eFightState on mobile. enum PedFightMoves @@ -93,13 +94,21 @@ enum PedFightMoves FIGHTMOVE_IDLE, FIGHTMOVE_SHUFFLE_F, FIGHTMOVE_KNEE, - FIGHTMOVE_HEADBUTT, - FIGHTMOVE_PUNCHJAB, FIGHTMOVE_PUNCHHOOK, - FIGHTMOVE_KICK, + FIGHTMOVE_PUNCHJAB, + FIGHTMOVE_PUNCH, + FIGHTMOVE_BODYBLOW = FIGHTMOVE_PUNCH, FIGHTMOVE_LONGKICK, FIGHTMOVE_ROUNDHOUSE, - FIGHTMOVE_BODYBLOW, + // Directionals + FIGHTMOVE_FWDLEFT, + FIGHTMOVE_FWDRIGHT, + FIGHTMOVE_BACKKICK, + FIGHTMOVE_BACKFLIP, + FIGHTMOVE_BACKLEFT, + FIGHTMOVE_BACKRIGHT, + FIGHTMOVE_RIGHTSWEEP, + // Special FIGHTMOVE_GROUNDKICK, // Opponent FIGHTMOVE_HITFRONT, @@ -112,6 +121,9 @@ enum PedFightMoves FIGHTMOVE_HITBIGSTEP, FIGHTMOVE_HITONFLOOR, FIGHTMOVE_HITBEHIND, + FIGHTMOVE_MELEE1, + FIGHTMOVE_MELEE2, + FIGHTMOVE_MELEE3, FIGHTMOVE_IDLE2NORM, NUM_FIGHTMOVES }; @@ -148,12 +160,28 @@ enum eWaitState { WAITSTATE_PLAYANIM_HANDSUP, WAITSTATE_PLAYANIM_HANDSCOWER, WAITSTATE_PLAYANIM_CHAT, - WAITSTATE_FINISH_FLEE + WAITSTATE_FINISH_FLEE, + WAITSTATE_SIT_DOWN, + WAITSTATE_SIT_DOWN_RVRS, + WAITSTATE_SIT_UP, + WAITSTATE_SIT_IDLE, + WAITSTATE_USE_ATM, + WAITSTATE_SUN_BATHE_PRE, + WAITSTATE_SUN_BATHE_DOWN, + WAITSTATE_SUN_BATHE_IDLE, + WAITSTATE_RIOT, + WAITSTATE_FAST_FALL, + WAITSTATE_BOMBER, + WAITSTATE_STRIPPER, + WAITSTATE_GROUND_ATTACK, + WAITSTATE_LANCESITTING, + WAITSTATE_PLAYANIM_HANDSUP_SIMPLE, }; enum eObjective : uint32 { OBJECTIVE_NONE, OBJECTIVE_IDLE, + OBJ_2, OBJECTIVE_FLEE_TILL_SAFE, OBJECTIVE_GUARD_SPOT, OBJECTIVE_GUARD_AREA, // not implemented @@ -165,6 +193,8 @@ enum eObjective : uint32 { OBJECTIVE_FLEE_CHAR_ON_FOOT_ALWAYS, OBJECTIVE_GOTO_CHAR_ON_FOOT, OBJECTIVE_FOLLOW_PED_IN_FORMATION, + OBJ_14, + OBJ_15, OBJECTIVE_LEAVE_VEHICLE, OBJECTIVE_ENTER_CAR_AS_PASSENGER, OBJECTIVE_ENTER_CAR_AS_DRIVER, @@ -175,8 +205,8 @@ enum eObjective : uint32 { OBJECTIVE_GOTO_AREA_ANY_MEANS, OBJECTIVE_GOTO_AREA_ON_FOOT, OBJECTIVE_RUN_TO_AREA, - OBJECTIVE_23, // not implemented - OBJECTIVE_24, // not implemented + OBJECTIVE_26, // not implemented + OBJECTIVE_27, // not implemented OBJECTIVE_FIGHT_CHAR, OBJECTIVE_SET_LEADER, OBJECTIVE_FOLLOW_ROUTE, @@ -185,11 +215,31 @@ enum eObjective : uint32 { OBJECTIVE_CATCH_TRAIN, OBJECTIVE_BUY_ICE_CREAM, OBJECTIVE_STEAL_ANY_CAR, + OBJ_36, OBJECTIVE_MUG_CHAR, + OBJECTIVE_LEAVE_CAR_AND_DIE, + OBJECTIVE_USE_SEAT_ATTRACTOR, + OBJECTIVE_USE_ATM_ATTRACTOR, OBJECTIVE_FLEE_CAR, -#ifdef VC_PED_PORTS - OBJECTIVE_LEAVE_CAR_AND_DIE -#endif + OBJ_42, + OBJECTIVE_USE_STOP_ATTRACTOR, + OBJECTIVE_USE_PIZZA_ATTRACTOR, + OBJECTIVE_USE_SHELTER_ATTRACTOR, + OBJECTIVE_AIM_GUN_AT_PED, + OBJ_47, + OBJECTIVE_WAIT_FOR_RAIN_TO_END, + OBJECTIVE_SPRINT_TO_COORD, + OBJ_50, + OBJ_51, + OBJECTIVE_WAIT_FOR_BUS, + OBJECTIVE_USE_ICECREAM_ATTRACTOR, + OBJECTIVE_PURCHASE_ICECREAM, + OBJ_55, + OBJ_56, + OBJ_57, + OBJ_58, + OBJ_59 + }; enum { @@ -379,26 +429,62 @@ public: uint32 bVehExitWillBeInstant : 1; uint32 bHasAlreadyBeenRecorded : 1; uint32 bFallenDown : 1; -#ifdef VC_PED_PORTS - uint32 bSomeVCflag1 : 1; -#endif #ifdef PED_SKIN uint32 bDontAcceptIKLookAts : 1; // TODO: find uses of this #endif + uint32 bReachedAttractorHeadingTarget : 1; + uint32 bTurnedAroundOnAttractor : 1; + + uint32 bHasAlreadyUsedAttractor : 1; + //uint32 b155_2 + uint32 bCarPassenger : 1; + //uint32 b155_8 + //uint32 b155_10 + uint32 bMiamiViceCop : 1; + uint32 bMoneyHasBeenGivenByScript : 1; // + uint32 bHasBeenPhotographed : 1; // + + uint32 bIsDrowning : 1; + uint32 bDrownsInWater : 1; + //uint32 b156_4 + uint32 b156_8 : 1; + uint32 bIsPlayerFriend : 1; +#ifdef VC_PED_PORTS + uint32 bHeadStuckInCollision : 1; +#endif + uint32 bDeadPedInFrontOfCar : 1; + uint32 bStayInCarOnJack : 1; + + uint32 bDontFight : 1; + uint32 bDoomAim : 1; + uint32 bCanBeShotInVehicle : 1; + //uint32 b157_8 + //uint32 b157_10 + //uint32 b157_20 + //uint32 b157_40 + uint32 bIgnoreThreatsBehindObjects : 1; + + uint32 bNeverEverTargetThisPed : 1; + //uint32 b158_2 + uint32 b158_4 : 1; + //uint32 b158_8 + //uint32 b158_10 + uint32 bBoughtIceCream : 1; + //uint32 b158_40 + //uint32 b158_80 + // our own flags uint32 m_ped_flagI40 : 1; // bMakePedsRunToPhonesToReportCrimes makes use of this as runover by car indicator uint32 m_ped_flagI80 : 1; // KANGAROO_CHEAT define makes use of this as cheat toggle - uint32 bCarPassenger : 1; - uint32 bMiamiViceCop : 1; // - uint32 bDeadPedInFrontOfCar : 1; - + uint8 m_gangFlags; uint8 CharCreatedBy; eObjective m_objective; eObjective m_prevObjective; CPed *m_pedInObjective; CVehicle *m_carInObjective; CVector m_nextRoutePointPos; + float m_attractorHeading; CPed *m_leader; eFormation m_pedFormation; uint32 m_fearFlags; @@ -437,6 +523,7 @@ public: CPathNode *m_pNextPathNode; float m_fHealth; float m_fArmour; + uint32 m_nExtendedRangeTimer; int16 m_routeLastPoint; uint16 m_routeStartPoint; int16 m_routePointsPassed; @@ -456,7 +543,9 @@ public: CVehicle *m_pMyVehicle; bool bInVehicle; float m_distanceToCountSeekDone; - + float m_acceptableHeadingOffset; + CPedAttractor* m_attractor; + int32 m_positionInQueue; CVehicle* m_vehicleInAccident; bool bRunningToPhone; @@ -478,7 +567,8 @@ public: CVector2D *m_wanderRangeBounds; // array with 2 CVector2D (actually unused CRange2D class) - unused CWeapon m_weapons[TOTAL_WEAPON_SLOTS]; eWeaponType m_storedWeapon; - uint32 m_storedWeaponAmmo; + eWeaponType m_delayedWeapon; + uint32 m_delayedWeaponAmmo; uint8 m_currentWeapon; // eWeaponType uint8 m_maxWeaponTypeAllowed; // eWeaponType uint8 m_wepSkills; @@ -489,6 +579,7 @@ public: uint8 m_fightButtonPressure; FightState m_fightState; bool m_takeAStepAfterAttack; + uint8 m_bleedCounter; CFire *m_pFire; CEntity *m_pLookTarget; float m_fLookDirection; @@ -505,13 +596,13 @@ public: uint32 m_duckAndCoverTimer; uint32 m_bloodyFootprintCountOrDeathTime; // Death time when bDoBloodyFootprints is false. Weird decision uint32 m_shotTime; - uint32 m_shotTimeAdd; + uint32 m_ceaseAttackTimer; uint8 m_panicCounter; bool m_deadBleeding; int8 m_bodyPartBleeding; // PedNode, but -1 if there isn't CPed *m_nearPeds[10]; uint16 m_numNearPeds; - uint16 m_pedMoney; + uint16 m_nPedMoney; int8 m_lastWepDam; CEntity *m_lastDamEntity; CEntity *m_attachedTo; @@ -574,7 +665,7 @@ public: void SetCurrentWeapon(eWeaponType weaponType); void SetCurrentWeapon(int weapon); void Duck(void); - void ClearDuck(void); + void ClearDuck(bool = false); void ClearPointGunAt(void); void BeingDraggedFromCar(void); void RestartNonPartialAnims(void); @@ -598,10 +689,11 @@ public: void SetObjective(eObjective, int16, int16); void SetObjective(eObjective, CVector); void SetObjective(eObjective, CVector, float); + void SetObjective(eObjective, float, const CVector&); void ClearChat(void); void InformMyGangOfAttack(CEntity*); void ReactToAttack(CEntity*); - void SetDuck(uint32); + void SetDuck(uint32, bool = false); void RegisterThreatWithGangPeds(CEntity*); bool TurnBody(void); void Chat(void); @@ -619,7 +711,9 @@ public: void SetPointGunAt(CEntity*); bool Seek(void); bool SetWanderPath(int8); - bool SetFollowPath(CVector); + bool SetFollowPath(CVector dest, float radius, eMoveState state, CEntity*, CEntity*, int); + bool SetFollowPathStatic(void); + bool SetFollowPathDynamic(void); void ClearAttackByRemovingAnim(void); void SetStoredState(void); void StopNonPartialAnims(void); @@ -658,6 +752,7 @@ public: void RemoveWeaponAnims(int, float); void CreateDeadPedMoney(void); void CreateDeadPedWeaponPickups(void); + void CreateDeadPedPickupCoors(float *x, float *y, float *z); void SetAttackTimer(uint32); void SetBeingDraggedFromCar(CVehicle*, uint32, bool); void SetRadioStation(void); @@ -728,6 +823,8 @@ public: void ClearFollowPath(); void GiveDelayedWeapon(eWeaponType weapon, uint32 ammo); void RequestDelayedWeapon(); + void AddInCarAnims(CVehicle* car, bool isDriver); + bool CanBeDamagedByThisGangMember(CPed*); // Static methods static CVector GetLocalPositionToOpenCarDoor(CVehicle *veh, uint32 component, float offset); @@ -767,6 +864,7 @@ public: static void PedSetDraggedOutCarPositionCB(CAnimBlendAssociation *assoc, void *arg); bool IsPlayer(void); + bool IsFemale(void) { return m_nPedType == PEDTYPE_CIVFEMALE || m_nPedType == PEDTYPE_PROSTITUTE; } bool UseGroundColModel(void); bool CanSetPedState(void); bool IsPedInControl(void); @@ -816,12 +914,20 @@ public: bool CanPedJumpThis(CEntity*); #endif + void SetNewAttraction(CPedAttractor* pAttractor, const CVector& pos, float, float, int); + void ClearWaitState(void); + bool HasWeaponSlot(uint8 slot) { return m_weapons[slot].m_eWeaponType != WEAPONTYPE_UNARMED; } - CWeapon &GetWeapon(uint8 slot) { return m_weapons[slot]; } + CWeapon& GetWeapon(uint8 slot) { return m_weapons[slot]; } CWeapon *GetWeapon(void) { return &m_weapons[m_currentWeapon]; } PedState GetPedState(void) { return m_nPedState; } - void SetPedState(PedState state) { m_nPedState = state; } + void SetPedState(PedState state) + { + if (GetPedState() == PED_FOLLOW_PATH) + ClearFollowPath(); + m_nPedState = state; + } bool Dead(void) { return m_nPedState == PED_DEAD; } bool Dying(void) { return m_nPedState == PED_DIE; } bool DyingOrDead(void) { return m_nPedState == PED_DIE || m_nPedState == PED_DEAD; } @@ -830,37 +936,63 @@ public: bool Driving(void) { return m_nPedState == PED_DRIVING; } bool InVehicle(void) { return bInVehicle && m_pMyVehicle; } // True when ped is sitting/standing in vehicle, not in enter/exit state. bool EnteringCar(void) { return m_nPedState == PED_ENTER_CAR || m_nPedState == PED_CARJACK; } + bool HasAttractor(void) { return m_attractor != nil; } + bool IsUseAttractorObjective(eObjective obj) { + return obj == OBJECTIVE_USE_ATM_ATTRACTOR || obj == OBJECTIVE_USE_ICECREAM_ATTRACTOR || + obj == OBJECTIVE_USE_PIZZA_ATTRACTOR || obj == OBJECTIVE_USE_SEAT_ATTRACTOR || + obj == OBJECTIVE_USE_SHELTER_ATTRACTOR || obj == OBJECTIVE_USE_STOP_ATTRACTOR; + } void ReplaceWeaponWhenExitingVehicle(void); void RemoveWeaponWhenEnteringVehicle(void); bool IsNotInWreckedVehicle(); - // My addons. Maybe inlined in VC? + // My names. Inlined in VC AnimationId GetFireAnimNotDucking(CWeaponInfo* weapon) { - // TODO(Miami): Revert that when weapons got ported - if (weapon->m_AnimToPlay == ASSOCGRP_STD) - return ANIM_FIGHT_PPUNCH; - if (m_nPedType == PEDTYPE_COP && !!weapon->m_bCop3rd) return ANIM_WEAPON_FIRE_3RD; else - return weapon->m_bAnimDetonate ? ANIM_BOMBER : ANIM_WEAPON_FIRE; + return GetPrimaryFireAnim(weapon); } static AnimationId GetFireAnimGround(CWeaponInfo* weapon, bool kickFloorIfNone = true) { - // TODO(Miami): Revert that when weapons got ported - if (weapon->m_AnimToPlay == ASSOCGRP_STD) - return ANIM_KICK_FLOOR; - if (!!weapon->m_bGround2nd) return ANIM_WEAPON_CROUCHFIRE; else if (!!weapon->m_bGround3rd) - return ANIM_WEAPON_SPECIAL; + return ANIM_WEAPON_FIRE_3RD; else if (kickFloorIfNone) return ANIM_KICK_FLOOR; else return (AnimationId)0; } + + static AnimationId GetPrimaryFireAnim(CWeaponInfo* weapon) { + if (weapon->m_bAnimDetonate) + return ANIM_BOMBER; + else + return ANIM_WEAPON_FIRE; + } + + static AnimationId GetCrouchReloadAnim(CWeaponInfo* weapon) { + if (!!weapon->m_bReload) + return ANIM_WEAPON_CROUCHRELOAD; + else + return (AnimationId)0; + } + + static AnimationId GetCrouchFireAnim(CWeaponInfo* weapon) { + if (!!weapon->m_bCrouchFire) + return ANIM_WEAPON_CROUCHFIRE; + else + return (AnimationId)0; + } + + static AnimationId GetReloadAnim(CWeaponInfo* weapon) { + if (!!weapon->m_bReload) + return ANIM_WEAPON_RELOAD; + else + return (AnimationId)0; + } // -- // My additions, because there were many, many instances of that. @@ -935,3 +1067,6 @@ void FinishFuckUCB(CAnimBlendAssociation *assoc, void *arg); #ifndef PED_SKIN VALIDATE_SIZE(CPed, 0x53C); #endif + +bool IsPedPointerValid(CPed*); +bool IsPedPointerValid_NotInWorld(CPed*); diff --git a/src/peds/PedAttractor.cpp b/src/peds/PedAttractor.cpp new file mode 100644 index 00000000..3d35b8a3 --- /dev/null +++ b/src/peds/PedAttractor.cpp @@ -0,0 +1,775 @@ +#include "common.h" +#include "PedAttractor.h" + +#include "General.h" +#include "Vehicle.h" +#include "World.h" + +const int gcMaxSizeOfAtmQueue = 1; +const int gcMaxSizeOfSeatQueue = 1; +const int gcMaxSizeOfStopQueue = 5; +const int gcMaxSizeOfPizzaQueue = 5; +const int gcMaxSizeOfShelterQueue = 5; +const int gcMaxSizeOfIceCreamQueue = 1; + +//--MIAMI: file done + +std::vector CPedShelterAttractor::ms_displacements; + +CPedAttractorManager* GetPedAttractorManager() +{ + static CPedAttractorManager manager; + return &manager; +} + +CVehicleToEffect::CVehicleToEffect(CVehicle* pVehicle) : m_pVehicle(pVehicle) +{ + m_effects[1].col = CRGBA(0, 0, 0, 0); + m_effects[1].type = EFFECT_PED_ATTRACTOR; + m_effects[1].pos = CVector(2.0f, 1.0f, 0.0f); + m_effects[1].pedattr.useDir = CVector(-1.0f, 0.0f, 0.0f); + m_effects[1].pedattr.queueDir = CVector(-1.0f, 0.0f, 0.0f); + m_effects[1].pedattr.type = ATTRACTOR_ICECREAM; + + m_effects[3].col = CRGBA(0, 0, 0, 0); + m_effects[3].type = EFFECT_PED_ATTRACTOR; + m_effects[3].pos = CVector(2.0f, -0.5f, 0.0f); + m_effects[3].pedattr.useDir = CVector(-1.0f, 0.0f, 0.0f); + m_effects[3].pedattr.queueDir = CVector(-1.0f, 0.0f, 0.0f); + m_effects[3].pedattr.type = ATTRACTOR_ICECREAM; + + m_effects[0].col = CRGBA(0, 0, 0, 0); + m_effects[0].type = EFFECT_PED_ATTRACTOR; + m_effects[0].pos = CVector(-2.0f, 1.0f, 0.0f); + m_effects[0].pedattr.useDir = CVector(1.0f, 0.0f, 0.0f); + m_effects[0].pedattr.queueDir = CVector(1.0f, 0.0f, 0.0f); + m_effects[0].pedattr.type = ATTRACTOR_ICECREAM; + + m_effects[2].col = CRGBA(0, 0, 0, 0); + m_effects[2].type = EFFECT_PED_ATTRACTOR; + m_effects[2].pos = CVector(-2.0f, -0.5f, 0.0f); + m_effects[2].pedattr.useDir = CVector(1.0f, 0.0f, 0.0f); + m_effects[2].pedattr.queueDir = CVector(1.0f, 0.0f, 0.0f); + m_effects[2].pedattr.type = ATTRACTOR_ICECREAM; +} + +CVehicleToEffect& CVehicleToEffect::From(const CVehicleToEffect& other) +{ + m_pVehicle = other.m_pVehicle; + for (int i = 0; i < NUM_ATTRACTORS_FOR_ICECREAM_VAN; i++) { + m_effects[i].col = other.m_effects[i].col; + m_effects[i].type = other.m_effects[i].type; + m_effects[i].pos = other.m_effects[i].pos; + m_effects[i].pedattr = other.m_effects[i].pedattr; + } + return *this; +} + +const C2dEffect* CVehicleToEffect::ChooseEffect(const CVector& pos) const +{ + if (!m_pVehicle) + return nil; + if (DotProduct(pos - m_pVehicle->GetPosition(), m_pVehicle->GetRight()) > 0.0f) { + if (DotProduct(pos - m_pVehicle->GetPosition(), m_pVehicle->GetForward()) > 0.0f) + return &m_effects[0]; + else + return &m_effects[2]; + } + else { + if (DotProduct(pos - m_pVehicle->GetPosition(), m_pVehicle->GetForward()) > 0.0f) + return &m_effects[1]; + else + return &m_effects[3]; + } +} + +bool CVehicleToEffect::HasThisEffect(C2dEffect* pEffect) const +{ + for (int i = 0; i < NUM_ATTRACTORS_FOR_ICECREAM_VAN; i++) { + if (pEffect == &m_effects[i]) + return true; + } + return false; +} + +const C2dEffect* CPedAttractorManager::GetEffectForIceCreamVan(CVehicle* pVehicle, const CVector& pos) +{ + if (!vVehicleToEffect.empty()) { + for (std::vector::const_iterator assoc = vVehicleToEffect.cbegin(); assoc != vVehicleToEffect.cend(); ++assoc) { + if (assoc->GetVehicle() == pVehicle) + return assoc->ChooseEffect(pos); + } + } + CVehicleToEffect effect(pVehicle); + vVehicleToEffect.push_back(effect); + return effect.ChooseEffect(pos); +} + +CVehicle* CPedAttractorManager::GetIceCreamVanForEffect(C2dEffect* pEffect) +{ + if (vVehicleToEffect.empty()) + return nil; + for (std::vector::const_iterator assoc = vVehicleToEffect.cbegin(); assoc != vVehicleToEffect.cend(); ++assoc) { + if (assoc->HasThisEffect(pEffect)) + return assoc->GetVehicle(); + } + return nil; +} + +const CPedAttractor* CPedAttractorManager::FindAssociatedAttractor(const C2dEffect* pEffect, std::vector& vecAttractors) +{ + if (vecAttractors.empty()) + return nil; + for (std::vector::const_iterator attractor = vecAttractors.cbegin(); attractor != vecAttractors.cend(); ++attractor) { + if ((*attractor)->GetEffect() == pEffect) + return *attractor; + } + return nil; +} + +void CPedAttractorManager::RemoveIceCreamVanEffects(C2dEffect* pEffect) +{ + CVehicle* pVehicle = GetIceCreamVanForEffect(pEffect); + if (!pVehicle) + return; + if (vVehicleToEffect.empty()) + return; + for (std::vector::const_iterator assoc = vVehicleToEffect.cbegin(); assoc != vVehicleToEffect.cend();) { + if (assoc->GetVehicle() != pVehicle) + return; + size_t total = 0; + for (size_t j = 0; j < NUM_ATTRACTORS_FOR_ICECREAM_VAN; j++) { + if (FindAssociatedAttractor(assoc->GetEffect(j), vIceCreamAttractors)) + total++; + } + if (total > 0) + assoc++; + else + assoc = vVehicleToEffect.erase(assoc); + } +} + +CPedAttractor::CPedAttractor(C2dEffect* pEffect, const CMatrix& matrix, int32 maxpeds, float qdist, float waitTime, float approachTime, float distance, float headingdiff, float posdisp, float headdisp) : + p2dEffect(pEffect), + m_nMaxPedsInAttractor(maxpeds), + m_fQueueDistance(qdist), + m_fTimeInWaitQueue(waitTime), + m_fTimeInApproachingQueue(approachTime), + m_fDistanceToUseAttractor(distance), + m_fAcceptableHeading(headingdiff), + m_fMaxPositionDisplacement(posdisp), + m_fMaxHeadingDisplacement(headdisp) +{ + CPedAttractorManager::ComputeEffectPos(pEffect, matrix, vecEffectPos); + CPedAttractorManager::ComputeEffectQueueDir(pEffect, matrix, vecQueueDir); + CPedAttractorManager::ComputeEffectUseDir(pEffect, matrix, vecUseDir); +} + +void CPedPizzaAttractor::UpdatePedStateOnDeparture(CPed* pPed) const +{ + if (pPed->m_nPedMoney > 10) + pPed->m_nPedMoney -= 10; + else + pPed->m_nPedMoney = 0; +} + +void CPedAtmAttractor::UpdatePedStateOnDeparture(CPed* pPed) const +{ + pPed->m_nPedMoney += 20 * CGeneral::GetRandomNumberInRange(1, 51); +}; + +float CPedAttractor::ComputeDeltaHeading() const +{ + return CGeneral::GetRandomNumberInRange(-m_fMaxHeadingDisplacement, m_fMaxHeadingDisplacement); +} + +float CPedAttractor::ComputeDeltaPos() const +{ + return CGeneral::GetRandomNumberInRange(-m_fMaxPositionDisplacement, m_fMaxPositionDisplacement); +} + +void CPedAttractor::ComputeAttractTime(int32 id, bool approacher, float& time) const +{ + if (approacher) + time = m_fTimeInApproachingQueue; + else + time = m_fTimeInWaitQueue; +} + +void CPedAttractor::ComputeAttractPos(int32 qid, CVector& pos) const +{ + if (!p2dEffect) + return; + pos = vecEffectPos - qid * vecQueueDir * m_fQueueDistance; + if (qid != 0) { + pos.x += ComputeDeltaPos(); + pos.y += ComputeDeltaPos(); + } +} + +CVector CPedShelterAttractor::GetDisplacement(int32 qid) const +{ + if (ms_displacements.empty()) { + int i = 0; + while (i < gcMaxSizeOfShelterQueue) { + float fRandomAngle = CGeneral::GetRandomNumberInRange(0.0f, TWOPI); + float fRandomOffset = CGeneral::GetRandomNumberInRange(0.0f, 2.0f); + CVector vecDisplacement(fRandomOffset * Sin(fRandomAngle), fRandomOffset * Cos(fRandomAngle), 0.0f); + bool close = false; + for (std::vector::const_iterator v = ms_displacements.cbegin(); v != ms_displacements.cend(); ++v) { + if ((*v - vecDisplacement).Magnitude() < 1.0f) { + close = true; + break; + } + } + if (!close) { + ms_displacements.push_back(vecDisplacement); + i++; + } + } + } + return ms_displacements[qid]; +} + +void CPedShelterAttractor::ComputeAttractPos(int32 qid, CVector& pos) const +{ + if (!p2dEffect) + return; + pos = vecEffectPos + GetDisplacement(qid); +} + +void CPedAttractor::ComputeAttractHeading(int32 qid, float& heading) const +{ + heading = CGeneral::GetRadianAngleBetweenPoints(qid != 0 ? vecQueueDir.x : vecUseDir.x, qid != 0 ? vecQueueDir.y : vecUseDir.y, 0.0f, 0.0f); + if (qid != 0) + heading += ComputeDeltaHeading(); +} + +void CPedShelterAttractor::ComputeAttractHeading(int32 qid, float& heading) const +{ + heading = CGeneral::GetRandomNumberInRange(0.0f, TWOPI); +} + +bool CPedAttractor::RegisterPed(CPed* pPed) +{ + for (std::vector::const_iterator pPedIt = vApproachingQueue.cbegin(); pPedIt != vApproachingQueue.cend(); ++pPedIt) { + if (*pPedIt == pPed) { + vApproachingQueue.erase(pPedIt); + return false; + } + } + if (GetNoOfRegisteredPeds() >= m_nMaxPedsInAttractor) + return 0; + vApproachingQueue.push_back(pPed); + CVector pos; + float heading; + float time; + int32 slot = ComputeFreeSlot(); + ComputeAttractPos(slot, pos); + ComputeAttractHeading(slot, heading); + ComputeAttractTime(slot, false, time); + pPed->SetNewAttraction(this, pos, heading, time, slot); + return true; +} + +static bool IsPedUsingAttractorOfThisType(int8 type, CPed* pPed) +{ + switch (type) { + case ATTRACTOR_ATM: + if (pPed->m_objective == OBJECTIVE_USE_ATM_ATTRACTOR) + return true; + break; + case ATTRACTOR_SEAT: + if (pPed->m_objective == OBJECTIVE_USE_SEAT_ATTRACTOR) + return true; + break; + case ATTRACTOR_STOP: + if (pPed->m_objective == OBJECTIVE_USE_STOP_ATTRACTOR || pPed->m_objective == OBJECTIVE_WAIT_FOR_BUS || pPed->m_objective == OBJECTIVE_IDLE) + return true; + break; + case ATTRACTOR_PIZZA: + if (pPed->m_objective == OBJECTIVE_USE_PIZZA_ATTRACTOR || pPed->m_objective == OBJECTIVE_IDLE) + return true; + break; + case ATTRACTOR_SHELTER: + if (pPed->m_objective == OBJECTIVE_USE_SHELTER_ATTRACTOR || pPed->m_objective == OBJECTIVE_WAIT_FOR_RAIN_TO_END) + return true; + break; + case ATTRACTOR_ICECREAM: + if (pPed->m_objective == OBJECTIVE_USE_ICECREAM_ATTRACTOR || pPed->m_objective == OBJECTIVE_PURCHASE_ICECREAM) + return true; + break; + } + return false; +} + +bool CPedAttractor::DeRegisterPed(CPed* pPed) +{ + for (std::vector::const_iterator pPedIt = vApproachingQueue.cbegin(); pPedIt != vApproachingQueue.cend(); ++pPedIt) { + if (*pPedIt != pPed) + continue; + pPed->m_attractor = nil; + pPed->m_positionInQueue = -1; + pPed->bHasAlreadyUsedAttractor = true; + + if (IsPedUsingAttractorOfThisType(p2dEffect->pedattr.type, pPed)) + pPed->SetObjective(OBJECTIVE_NONE); + else if (pPed->GetPedState() != PED_IDLE && pPed->GetPedState() != PED_NONE) { + vApproachingQueue.erase(pPedIt); + return true; + } + pPed->SetWanderPath(CGeneral::GetNodeHeadingFromVector(-vecQueueDir.x, -vecQueueDir.y)); + vApproachingQueue.erase(pPedIt); + return true; + } + return BroadcastDeparture(pPed); +} + +bool CPedAttractor::BroadcastArrival(CPed* pPed) +{ + for (std::vector::const_iterator pPedIt = vWaitingQueue.cbegin(); pPedIt != vWaitingQueue.cend(); ++pPedIt) { + if (*pPedIt == pPed) + return false; + } + vWaitingQueue.push_back(pPed); + for (std::vector::const_iterator pPedIt = vApproachingQueue.cbegin(); pPedIt != vApproachingQueue.cend(); ++pPedIt) { + if (*pPedIt == pPed) { + vApproachingQueue.erase(pPedIt); + break; + } + } + for (std::vector::iterator pPedIt = vApproachingQueue.begin(); pPedIt != vApproachingQueue.end(); ++pPedIt) { + CPed* pPed = *pPedIt; + CVector pos; + float heading; + float time; + int32 slot = ComputeFreeSlot(); + ComputeAttractPos(slot, pos); + ComputeAttractHeading(slot, heading); + ComputeAttractTime(slot, false, time); + pPed->SetNewAttraction(this, pos, heading, time, slot); + } + return true; +} + +bool CPedAttractor::BroadcastDeparture(CPed* pPed) +{ + int qid = -1; + for (size_t i = 0; i < vWaitingQueue.size(); i++){ + if (vWaitingQueue[i] == pPed) + qid = i; + } + if (qid < 0) + return false; + for (size_t i = qid + 1; i < vWaitingQueue.size(); i++) { + CVector pos; + float heading; + float time; + ComputeAttractPos(i - 1, pos); + ComputeAttractHeading(i - 1, heading); + ComputeAttractTime(i - 1, true, time); + pPed->SetNewAttraction(this, pos, heading, time, i - 1); + } + pPed->m_attractor = nil; + pPed->m_positionInQueue = -1; + pPed->bHasAlreadyUsedAttractor = true; + if (!IsPedUsingAttractorOfThisType(p2dEffect->pedattr.type, pPed)) { + if (pPed->GetPedState() == PED_IDLE || pPed->GetPedState() == PED_NONE) + pPed->SetWanderPath(CGeneral::GetNodeHeadingFromVector(-vecQueueDir.x, -vecQueueDir.y)); + } + else if (qid == 0) + pPed->SetWanderPath(CGeneral::GetNodeHeadingFromVector(vecQueueDir.x, vecQueueDir.y)); + else if (qid == vWaitingQueue.size() - 1) + pPed->SetWanderPath(CGeneral::GetNodeHeadingFromVector(-vecQueueDir.x, -vecQueueDir.y)); + else + pPed->SetWanderPath(CGeneral::GetNodeHeadingFromVector(-vecQueueDir.y, -vecQueueDir.z)); + vWaitingQueue.erase(vWaitingQueue.cbegin() + qid); + for (std::vector::iterator pPedIt = vApproachingQueue.begin(); pPedIt != vApproachingQueue.end(); ++pPedIt) { + CPed* pPed = *pPedIt; + CVector pos; + float heading; + float time; + int32 slot = ComputeFreeSlot(); + ComputeAttractPos(slot, pos); + ComputeAttractHeading(slot, heading); + ComputeAttractTime(slot, false, time); + pPed->SetNewAttraction(this, pos, heading, time, slot); + } + return true; +} + +bool CPedShelterAttractor::BroadcastDeparture(CPed* pPed) +{ + int qid = -1; + for (size_t i = 0; i < vWaitingQueue.size(); i++) { + if (vWaitingQueue[i] == pPed) + qid = i; + } + if (qid < 0) + return false; + pPed->m_attractor = nil; + pPed->m_positionInQueue = -1; + pPed->bHasAlreadyUsedAttractor = true; + if (!IsPedUsingAttractorOfThisType(p2dEffect->pedattr.type, pPed)) { + if (pPed->GetPedState() == PED_IDLE || pPed->GetPedState() == PED_NONE) + pPed->SetWanderPath(CGeneral::GetNodeHeadingFromVector(-vecQueueDir.x, -vecQueueDir.y)); + } + else if (qid == 0) + pPed->SetWanderPath(CGeneral::GetNodeHeadingFromVector(vecQueueDir.x, vecQueueDir.y)); + else if (qid == vWaitingQueue.size() - 1) + pPed->SetWanderPath(CGeneral::GetNodeHeadingFromVector(-vecQueueDir.x, -vecQueueDir.y)); + else + pPed->SetWanderPath(CGeneral::GetNodeHeadingFromVector(-vecQueueDir.y, -vecQueueDir.z)); + vWaitingQueue.erase(vWaitingQueue.cbegin() + qid); + for (std::vector::iterator pPedIt = vApproachingQueue.begin(); pPedIt != vApproachingQueue.end(); ++pPedIt) { + CPed* pPed = *pPedIt; + CVector pos; + float heading; + float time; + int32 slot = ComputeFreeSlot(); + ComputeAttractPos(slot, pos); + ComputeAttractHeading(slot, heading); + ComputeAttractTime(slot, false, time); + pPed->SetNewAttraction(this, pos, heading, time, slot); + } + return true; +} + +bool CPedAttractor::IsRegisteredWithPed(CPed* pPed) const +{ + for (std::vector::const_iterator pPedIt = vWaitingQueue.cbegin(); pPedIt != vWaitingQueue.cend(); ++pPedIt) { + if (*pPedIt == pPed) + return true; + } + for (std::vector::const_iterator pPedIt = vApproachingQueue.cbegin(); pPedIt != vApproachingQueue.cend(); ++pPedIt) { + if (*pPedIt == pPed) { + return true; + } + } + return false; +} + +bool CPedAttractor::IsInQueue(CPed* pPed) const +{ + for (std::vector::const_iterator pPedIt = vWaitingQueue.cbegin(); pPedIt != vWaitingQueue.cend(); ++pPedIt) { + if (*pPedIt == pPed) + return true; + } + return false; +} + +CPedAttractor* CPedAttractorManager::RegisterPedWithAttractor(CPed* pPed, C2dEffect* pEffect, const CMatrix& matrix) +{ + if (pEffect->type != EFFECT_PED_ATTRACTOR) + return nil; + if (IsPedRegisteredWithEffect(pPed)) + return nil; + switch (pEffect->pedattr.type) { + case ATTRACTOR_ATM: return RegisterPed(pPed, pEffect, matrix, vAtmAttractors); + case ATTRACTOR_SEAT: return RegisterPed(pPed, pEffect, matrix, vSeatAttractors); + case ATTRACTOR_STOP: return RegisterPed(pPed, pEffect, matrix, vStopAttractors); + case ATTRACTOR_PIZZA: return RegisterPed(pPed, pEffect, matrix, vPizzaAttractors); + case ATTRACTOR_SHELTER: return RegisterPed(pPed, pEffect, matrix, vShelterAttractors); + case ATTRACTOR_ICECREAM: return RegisterPed(pPed, pEffect, matrix, vIceCreamAttractors); + } + return nil; +} + +bool CPedAttractorManager::DeRegisterPed(CPed* pPed, CPedAttractor* pAttractor) +{ + if (!pAttractor) + return false; + if (pAttractor->GetEffect()->type != EFFECT_PED_ATTRACTOR) + return nil; + if (!IsPedRegisteredWithEffect(pPed)) + return nil; + switch (pAttractor->GetEffect()->pedattr.type) { + case ATTRACTOR_ATM: return DeRegisterPed(pPed, pAttractor, vAtmAttractors); + case ATTRACTOR_SEAT: return DeRegisterPed(pPed, pAttractor, vSeatAttractors); + case ATTRACTOR_STOP: return DeRegisterPed(pPed, pAttractor, vStopAttractors); + case ATTRACTOR_PIZZA: return DeRegisterPed(pPed, pAttractor, vPizzaAttractors); + case ATTRACTOR_SHELTER: return DeRegisterPed(pPed, pAttractor, vShelterAttractors); + case ATTRACTOR_ICECREAM: return DeRegisterPed(pPed, pAttractor, vIceCreamAttractors); + } + return nil; +} + +bool CPedAttractorManager::BroadcastArrival(CPed* pPed, CPedAttractor* pAttractor) +{ + if (!pAttractor) + return false; + if (pAttractor->GetEffect()->type != EFFECT_PED_ATTRACTOR) + return nil; + if (!IsPedRegisteredWithEffect(pPed)) + return nil; + switch (pAttractor->GetEffect()->pedattr.type) { + case ATTRACTOR_ATM: return BroadcastArrival(pPed, pAttractor, vAtmAttractors); + case ATTRACTOR_SEAT: return BroadcastArrival(pPed, pAttractor, vSeatAttractors); + case ATTRACTOR_STOP: return BroadcastArrival(pPed, pAttractor, vStopAttractors); + case ATTRACTOR_PIZZA: return BroadcastArrival(pPed, pAttractor, vPizzaAttractors); + case ATTRACTOR_SHELTER: return BroadcastArrival(pPed, pAttractor, vShelterAttractors); + case ATTRACTOR_ICECREAM: return BroadcastArrival(pPed, pAttractor, vIceCreamAttractors); + } + return nil; +} + +bool CPedAttractorManager::BroadcastDeparture(CPed* pPed, CPedAttractor* pAttractor) +{ + if (!pAttractor) + return false; + if (pAttractor->GetEffect()->type != EFFECT_PED_ATTRACTOR) + return nil; + if (!IsPedRegisteredWithEffect(pPed)) + return nil; + switch (pAttractor->GetEffect()->pedattr.type) { + case ATTRACTOR_ATM: return BroadcastDeparture(pPed, pAttractor, vAtmAttractors); + case ATTRACTOR_SEAT: return BroadcastDeparture(pPed, pAttractor, vSeatAttractors); + case ATTRACTOR_STOP: return BroadcastDeparture(pPed, pAttractor, vStopAttractors); + case ATTRACTOR_PIZZA: return BroadcastDeparture(pPed, pAttractor, vPizzaAttractors); + case ATTRACTOR_SHELTER: return BroadcastDeparture(pPed, pAttractor, vShelterAttractors); + case ATTRACTOR_ICECREAM: return BroadcastDeparture(pPed, pAttractor, vIceCreamAttractors); + } + return nil; +} + +bool CPedAttractorManager::IsAtHeadOfQueue(CPed* pPed, CPedAttractor* pAttractor) +{ + if (!pAttractor) + return false; + if (pAttractor->GetEffect()->type != EFFECT_PED_ATTRACTOR) + return nil; + if (!IsPedRegisteredWithEffect(pPed)) + return nil; + switch (pAttractor->GetEffect()->pedattr.type) { + case ATTRACTOR_ATM: return IsAtHeadOfQueue(pPed, pAttractor, vAtmAttractors); + case ATTRACTOR_SEAT: return IsAtHeadOfQueue(pPed, pAttractor, vSeatAttractors); + case ATTRACTOR_STOP: return IsAtHeadOfQueue(pPed, pAttractor, vStopAttractors); + case ATTRACTOR_PIZZA: return IsAtHeadOfQueue(pPed, pAttractor, vPizzaAttractors); + case ATTRACTOR_SHELTER: return IsAtHeadOfQueue(pPed, pAttractor, vShelterAttractors); + case ATTRACTOR_ICECREAM: return IsAtHeadOfQueue(pPed, pAttractor, vIceCreamAttractors); + } + return nil; +} + +bool CPedAttractorManager::IsInQueue(CPed* pPed, CPedAttractor* pAttractor) +{ + if (!pAttractor) + return false; + if (pAttractor->GetEffect()->type != EFFECT_PED_ATTRACTOR) + return nil; + if (!IsPedRegisteredWithEffect(pPed)) + return nil; + switch (pAttractor->GetEffect()->pedattr.type) { + case ATTRACTOR_ATM: return IsInQueue(pPed, pAttractor, vAtmAttractors); + case ATTRACTOR_SEAT: return IsInQueue(pPed, pAttractor, vSeatAttractors); + case ATTRACTOR_STOP: return IsInQueue(pPed, pAttractor, vStopAttractors); + case ATTRACTOR_PIZZA: return IsInQueue(pPed, pAttractor, vPizzaAttractors); + case ATTRACTOR_SHELTER: return IsInQueue(pPed, pAttractor, vShelterAttractors); + case ATTRACTOR_ICECREAM: return IsInQueue(pPed, pAttractor, vIceCreamAttractors); + } + return nil; +} + +bool CPedAttractorManager::HasEmptySlot(const C2dEffect* pEffect) +{ + if (!pEffect) + return false; + if (pEffect->type != EFFECT_PED_ATTRACTOR) + return nil; + const CPedAttractor* pAttractor; + switch (pEffect->pedattr.type) { + case ATTRACTOR_ATM: pAttractor = FindAssociatedAttractor(pEffect, vAtmAttractors); break; + case ATTRACTOR_SEAT: pAttractor = FindAssociatedAttractor(pEffect, vSeatAttractors); break; + case ATTRACTOR_STOP: pAttractor = FindAssociatedAttractor(pEffect, vStopAttractors); break; + case ATTRACTOR_PIZZA: pAttractor = FindAssociatedAttractor(pEffect, vPizzaAttractors); break; + case ATTRACTOR_SHELTER: pAttractor = FindAssociatedAttractor(pEffect, vShelterAttractors); break; + case ATTRACTOR_ICECREAM: pAttractor = FindAssociatedAttractor(pEffect, vIceCreamAttractors); break; + default: return true; + } + if (!pAttractor) + return true; + return pAttractor->GetNoOfRegisteredPeds() < pAttractor->GetMaxPedsInAttractor(); +} + +bool CPedAttractorManager::IsPedRegisteredWithEffect(CPed* pPed) +{ + return IsPedRegistered(pPed, vAtmAttractors) || + IsPedRegistered(pPed, vSeatAttractors) || + IsPedRegistered(pPed, vStopAttractors) || + IsPedRegistered(pPed, vPizzaAttractors) || + IsPedRegistered(pPed, vShelterAttractors) || + IsPedRegistered(pPed, vIceCreamAttractors); +} + +void CPedAttractorManager::ComputeEffectPos(const C2dEffect* pEffect, const CMatrix& matrix, CVector& pos) +{ + pos = matrix.GetPosition() + Multiply3x3(matrix, pEffect->pos); +} + +void CPedAttractorManager::ComputeEffectQueueDir(const C2dEffect* pEffect, const CMatrix& matrix, CVector& pos) +{ + pos = Multiply3x3(matrix, pEffect->pedattr.queueDir); +} + +void CPedAttractorManager::ComputeEffectUseDir(const C2dEffect* pEffect, const CMatrix& matrix, CVector& pos) +{ + pos = Multiply3x3(matrix, pEffect->pedattr.useDir); +} + +CPedAttractor* CPedAttractorManager::RegisterPed(CPed* pPed, C2dEffect* pEffect, const CMatrix& matrix, std::vector& vecAttractors) +{ + CPedAttractor* pRegisteredAttractor = nil; + for (std::vector::const_iterator pAttractorIt = vecAttractors.cbegin(); pAttractorIt != vecAttractors.cend(); ++pAttractorIt) { + CPedAttractor* pAttractor = *pAttractorIt; + CVector vEffectPos; + ComputeEffectPos(pAttractor->GetEffect(), matrix, vEffectPos); + if (pAttractor->GetEffect() == pEffect && vEffectPos == pAttractor->GetEffectPos()) { + if (!IsApproachable(pEffect, matrix, pAttractor->ComputeFreeSlot(), pPed)) + return nil; + pRegisteredAttractor = pAttractor; + break; + } + } + if (pRegisteredAttractor || !IsApproachable(pEffect, matrix, 0, pPed)) { + if (pRegisteredAttractor) + pRegisteredAttractor->RegisterPed(pPed); + return pRegisteredAttractor; + } + switch (pEffect->pedattr.type) { + case ATTRACTOR_ATM: vecAttractors.push_back(new CPedAtmAttractor(pEffect, matrix, gcMaxSizeOfAtmQueue, 1.0f, 30000.0f, 3000.0f, 0.2f, 0.15f, 0.1f, 0.1f)); break; + case ATTRACTOR_SEAT: vecAttractors.push_back(new CPedSeatAttractor(pEffect, matrix, gcMaxSizeOfSeatQueue, 1.0f, 30000.0f, 3000.0f, 0.125f, 0.1f, 0.1f, 0.1f)); break; + case ATTRACTOR_STOP: vecAttractors.push_back(new CPedStopAttractor(pEffect, matrix, gcMaxSizeOfStopQueue, 1.0f, 30000.0f, 3000.0f, 0.2f, 0.1f, 0.1f, 0.1f)); break; + case ATTRACTOR_PIZZA: vecAttractors.push_back(new CPedPizzaAttractor(pEffect, matrix, gcMaxSizeOfPizzaQueue, 1.0f, 30000.0f, 3000.0f, 0.2f, 0.1f, 0.1f, 0.1f)); break; + case ATTRACTOR_SHELTER: vecAttractors.push_back(new CPedShelterAttractor(pEffect, matrix, gcMaxSizeOfShelterQueue, 1.0f, 30000.0f, 3000.0f, 0.5f, 6.28f, 0.1f, 0.1f)); break; + case ATTRACTOR_ICECREAM: vecAttractors.push_back(new CPedIceCreamAttractor(pEffect, matrix, gcMaxSizeOfIceCreamQueue, 1.0f, 30000.0f, 3000.0f, 0.2f, 0.3f, 0.1f, 0.1f)); break; + } + if (pRegisteredAttractor) + pRegisteredAttractor->RegisterPed(pPed); + return pRegisteredAttractor; +} + +bool CPedAttractorManager::DeRegisterPed(CPed* pPed, CPedAttractor* pAttractor, std::vector& vecAttractors) +{ + if (!pAttractor) + return false; + CPedAttractor* pFound = nil; + for (std::vector::const_iterator pAttractorIt = vecAttractors.cbegin(); pAttractorIt != vecAttractors.cend(); ++pAttractorIt) { + if (*pAttractorIt == pAttractor) { + pFound = *pAttractorIt; + break; + } + } + if (!pFound) + return false; + pFound->DeRegisterPed(pPed); + if (pFound->GetNoOfRegisteredPeds() != 0) + return true; + for (std::vector::const_iterator pAttractorIt = vecAttractors.cbegin(); pAttractorIt != vecAttractors.cend(); ++pAttractorIt) { + if (*pAttractorIt == pAttractor) { + vecAttractors.erase(pAttractorIt); + break; + } + } + delete pAttractor; + return true; +} + +bool CPedAttractorManager::BroadcastArrival(CPed* pPed, CPedAttractor* pAttractor, std::vector& vecAttractors) +{ + if (!pAttractor) + return false; + CPedAttractor* pFound = nil; + for (std::vector::const_iterator pAttractorIt = vecAttractors.cbegin(); pAttractorIt != vecAttractors.cend(); ++pAttractorIt) { + if (*pAttractorIt == pAttractor) { + pFound = *pAttractorIt; + break; + } + } + if (!pFound) + return false; + pFound->BroadcastArrival(pPed); + return true; +} + +bool CPedAttractorManager::BroadcastDeparture(CPed* pPed, CPedAttractor* pAttractor, std::vector& vecAttractors) +{ + if (!pAttractor) + return false; + CPedAttractor* pFound = nil; + for (std::vector::const_iterator pAttractorIt = vecAttractors.cbegin(); pAttractorIt != vecAttractors.cend(); ++pAttractorIt) { + if (*pAttractorIt == pAttractor) { + pFound = *pAttractorIt; + break; + } + } + if (!pFound) + return false; + pFound->DeRegisterPed(pPed); + if (pFound->GetNoOfRegisteredPeds() != 0) + return true; + for (std::vector::const_iterator pAttractorIt = vecAttractors.cbegin(); pAttractorIt != vecAttractors.cend(); ++pAttractorIt) { + if (*pAttractorIt == pAttractor) { + vecAttractors.erase(pAttractorIt); + break; + } + } + delete pAttractor; + return true; +} + +bool CPedAttractorManager::IsInQueue(CPed* pPed, CPedAttractor* pAttractor, std::vector& vecAttractors) +{ + if (!pAttractor) + return false; + for (std::vector::const_iterator pAttractorIt = vecAttractors.cbegin(); pAttractorIt != vecAttractors.cend(); ++pAttractorIt) { + if (*pAttractorIt == pAttractor) { + return (*pAttractorIt)->IsInQueue(pPed); + } + } + return false; +} + +bool CPedAttractorManager::IsAtHeadOfQueue(CPed* pPed, CPedAttractor* pAttractor, std::vector& vecAttractors) +{ + if (!pAttractor) + return false; + for (std::vector::const_iterator pAttractorIt = vecAttractors.cbegin(); pAttractorIt != vecAttractors.cend(); ++pAttractorIt) { + if (*pAttractorIt == pAttractor) { + return (*pAttractorIt)->IsAtHeadOfQueue(pPed); + } + } + return false; +} + +bool CPedAttractorManager::IsPedRegistered(CPed* pPed, std::vector& vecAttractors) +{ + for (std::vector::const_iterator pAttractorIt = vecAttractors.cbegin(); pAttractorIt != vecAttractors.cend(); ++pAttractorIt) { + if ((*pAttractorIt)->IsRegisteredWithPed(pPed)) + return true; + } + return false; +} + +bool CPedAttractorManager::IsApproachable(C2dEffect* pEffect, const CMatrix& matrix, int32, CPed* pPed) +{ + if (pEffect->pedattr.type == ATTRACTOR_SHELTER) { + CVector pos; + ComputeEffectPos(pEffect, matrix, pos); + return CWorld::GetIsLineOfSightClear(pPed->GetPosition(), pos, true, false, false, false, false, false); + } + CVector vecUseDir, vecEffectPos; + ComputeEffectUseDir(pEffect, matrix, vecUseDir); + ComputeEffectPos(pEffect, matrix, vecEffectPos); + float dp = -DotProduct(vecUseDir, vecEffectPos); + if (pEffect->pedattr.type == ATTRACTOR_ATM || pEffect->pedattr.type == ATTRACTOR_PIZZA || pEffect->pedattr.type == ATTRACTOR_ICECREAM) { + vecUseDir = -vecUseDir; + dp = -dp; + } + if (dp + DotProduct(vecEffectPos, pPed->GetPosition()) > 0.0f) { + CVector vecPedToAttractor = pPed->GetPosition() - vecEffectPos; + vecPedToAttractor.Normalise(); + if (DotProduct(vecPedToAttractor, vecUseDir) > 0.25f && CWorld::IsWanderPathClear(pPed->GetPosition(), vecEffectPos, 2.0f, 0)) + return true; + } + return false; +} diff --git a/src/peds/PedAttractor.h b/src/peds/PedAttractor.h new file mode 100644 index 00000000..563efd3a --- /dev/null +++ b/src/peds/PedAttractor.h @@ -0,0 +1,196 @@ +#pragma once +#include "common.h" +#include + +#include "2dEffect.h" +#include "Ped.h" + +#define NUM_ATTRACTORS_FOR_ICECREAM_VAN 4 + +class CPedAttractor; + +class CVehicleToEffect +{ + CVehicle* m_pVehicle; + C2dEffect m_effects[NUM_ATTRACTORS_FOR_ICECREAM_VAN]; + +public: + CVehicleToEffect(CVehicle* pVehicle); + const C2dEffect* ChooseEffect(const CVector& pos) const; + CVehicleToEffect& From(const CVehicleToEffect& other); + CVehicleToEffect& operator=(const CVehicleToEffect& other) { return From(other); } + ~CVehicleToEffect() { m_pVehicle = nil; } + CVehicle* GetVehicle() const { return m_pVehicle; } + bool HasThisEffect(C2dEffect* pEffect) const; + const C2dEffect* GetEffect(int32 i) const { return &m_effects[i]; } +}; + +class CPedAttractorManager +{ + std::vector vAtmAttractors; + std::vector vSeatAttractors; + std::vector vStopAttractors; + std::vector vPizzaAttractors; + std::vector vShelterAttractors; + std::vector vIceCreamAttractors; + std::vector vVehicleToEffect; + +public: + CPedAttractor* RegisterPedWithAttractor(CPed* pPed, C2dEffect* pEffect, const CMatrix& matrix); + CPedAttractor* RegisterPed(CPed* pPed, C2dEffect* pEffect, const CMatrix& matrix, std::vector& vecAttractors); + bool BroadcastArrival(CPed* pPed, CPedAttractor* pAttractor); + bool BroadcastArrival(CPed* pPed, CPedAttractor* pAttractor, std::vector& vecAttractors); + const C2dEffect* GetEffectForIceCreamVan(CVehicle* pVehicle, const CVector& pos); + bool IsApproachable(C2dEffect* pEffect, const CMatrix& matrix, int32, CPed* pPed); + void RemoveIceCreamVanEffects(C2dEffect* pEffect); + bool HasEmptySlot(const C2dEffect* pEffect); + const CPedAttractor* FindAssociatedAttractor(const C2dEffect* pEffect, std::vector& vecAttractors); + bool IsInQueue(CPed* pPed, CPedAttractor* pAttractor); + bool IsInQueue(CPed* pPed, CPedAttractor* pAttractor, std::vector& vecAttractors); + bool IsAtHeadOfQueue(CPed* pPed, CPedAttractor* pAttractor); + bool IsAtHeadOfQueue(CPed* pPed, CPedAttractor* pAttractor, std::vector& vecAttractors); + bool BroadcastDeparture(CPed* pPed, CPedAttractor* pAttractor); + bool BroadcastDeparture(CPed* pPed, CPedAttractor* pAttractor, std::vector& vecAttractors); + bool DeRegisterPed(CPed* pPed, CPedAttractor* pAttractor); + bool DeRegisterPed(CPed* pPed, CPedAttractor* pAttractor, std::vector& vecAttractors); + bool IsPedRegisteredWithEffect(CPed* pPed); + bool IsPedRegistered(CPed* pPed, std::vector& vecAttractors); + CVehicle* GetIceCreamVanForEffect(C2dEffect* pEffect); + + static void ComputeEffectPos(const C2dEffect* pEffect, const CMatrix& matrix, CVector& pos); + static void ComputeEffectQueueDir(const C2dEffect* pEffect, const CMatrix& matrix, CVector& pos); + static void ComputeEffectUseDir(const C2dEffect* pEffect, const CMatrix& matrix, CVector& pos); + +}; + +CPedAttractorManager* GetPedAttractorManager(); + +enum ePedAttractorType +{ + ATTRACTOR_ATM = 0, + ATTRACTOR_SEAT, + ATTRACTOR_STOP, + ATTRACTOR_PIZZA, + ATTRACTOR_SHELTER, + ATTRACTOR_ICECREAM +}; + +class CPedAttractor +{ +protected: + C2dEffect* p2dEffect; + std::vector vApproachingQueue; + std::vector vWaitingQueue; + int32 m_nMaxPedsInAttractor; + float m_fQueueDistance; + float m_fTimeInWaitQueue; + float m_fTimeInApproachingQueue; + float m_fDistanceToUseAttractor; + float m_fAcceptableHeading; + float m_fMaxPositionDisplacement; + float m_fMaxHeadingDisplacement; + CVector vecEffectPos; + CVector vecQueueDir; + CVector vecUseDir; + +public: + virtual float GetHeadOfQueueWaitTime() { return 0.0f; } + virtual ~CPedAttractor() {}; + virtual ePedAttractorType GetType() const = 0; + virtual void UpdatePedStateOnDeparture(CPed* pPed) const = 0; + virtual bool IsAtHeadOfQueue(CPed* pPed) const { return vWaitingQueue.front() == pPed; } + virtual void ComputeAttractPos(int32 id, CVector& pos) const; + virtual void ComputeAttractHeading(int32 id, float& pHeading) const; + virtual bool BroadcastDeparture(CPed* pPed); + + bool IsRegisteredWithPed(CPed* pPed) const; + bool DeRegisterPed(CPed* pPed); + float ComputeDeltaHeading() const; + float ComputeDeltaPos() const; + void ComputeAttractTime(int32 id, bool, float& time) const; + int32 GetNoOfRegisteredPeds() const { return vWaitingQueue.size() + vApproachingQueue.size(); } + int32 ComputeFreeSlot() const { return vWaitingQueue.size(); } + bool IsInQueue(CPed*) const; + bool RegisterPed(CPed*); + bool BroadcastArrival(CPed*); + + CPedAttractor(C2dEffect* pEffect, const CMatrix& matrix, int32 maxpeds, float qdist, float waitTime, float approachTime, float distance, float headingdiff, float posdisp, float headdisp); + + C2dEffect* GetEffect() const { return p2dEffect; } + const CVector& GetEffectPos() const { return vecEffectPos; } + int32 GetMaxPedsInAttractor() const { return m_nMaxPedsInAttractor; } + float GetDistanceToCountSeekDone() const { return m_fDistanceToUseAttractor; } + float GetAcceptableHeading() const { return m_fAcceptableHeading; } +}; + +class CPedAtmAttractor : public CPedAttractor +{ +public: + virtual ePedAttractorType GetType() const override { return ATTRACTOR_ATM; }; + virtual void UpdatePedStateOnDeparture(CPed* pPed) const override; + CPedAtmAttractor(C2dEffect* pEffect, const CMatrix& matrix, int32 maxpeds, float qdist, float waitTime, float approachTime, float distance, float headingdiff, float posdisp, float headdisp) : + CPedAttractor(pEffect, matrix, maxpeds, qdist, waitTime, approachTime, distance, headingdiff, posdisp, headdisp) + {}; +}; + +class CPedIceCreamAttractor : public CPedAttractor +{ +public: + virtual ~CPedIceCreamAttractor() override { GetPedAttractorManager()->RemoveIceCreamVanEffects(p2dEffect); } + virtual ePedAttractorType GetType() const override { return ATTRACTOR_ICECREAM; } + virtual void UpdatePedStateOnDeparture(CPed* pPed) const override {}; + CPedIceCreamAttractor(C2dEffect* pEffect, const CMatrix& matrix, int32 maxpeds, float qdist, float waitTime, float approachTime, float distance, float headingdiff, float posdisp, float headdisp) : + CPedAttractor(pEffect, matrix, maxpeds, qdist, waitTime, approachTime, distance, headingdiff, posdisp, headdisp) + {}; +}; + +class CPedPizzaAttractor : public CPedAttractor +{ +public: + virtual float GetHeadOfQueueWaitTime() override { return 2000.0f; } + virtual ePedAttractorType GetType() const override { return ATTRACTOR_PIZZA; } + virtual void UpdatePedStateOnDeparture(CPed* pPed) const override; + CPedPizzaAttractor(C2dEffect* pEffect, const CMatrix& matrix, int32 maxpeds, float qdist, float waitTime, float approachTime, float distance, float headingdiff, float posdisp, float headdisp) : + CPedAttractor(pEffect, matrix, maxpeds, qdist, waitTime, approachTime, distance, headingdiff, posdisp, headdisp) + {}; +}; + +class CPedSeatAttractor : public CPedAttractor +{ +public: + virtual ePedAttractorType GetType() const override { return ATTRACTOR_SEAT; } + virtual void UpdatePedStateOnDeparture(CPed* pPed) const override {}; + CPedSeatAttractor(C2dEffect* pEffect, const CMatrix& matrix, int32 maxpeds, float qdist, float waitTime, float approachTime, float distance, float headingdiff, float posdisp, float headdisp) : + CPedAttractor(pEffect, matrix, maxpeds, qdist, waitTime, approachTime, distance, headingdiff, posdisp, headdisp) + {}; +}; + +class CPedShelterAttractor : public CPedAttractor +{ + static std::vector ms_displacements; +public: + virtual ePedAttractorType GetType() const override { return ATTRACTOR_SHELTER; } + virtual bool BroadcastDeparture(CPed*) override; + virtual void UpdatePedStateOnDeparture(CPed* pPed) const override {}; + virtual bool IsAtHeadOfQueue(CPed* pPed) const override { return true; } + virtual void ComputeAttractPos(int qid, CVector& pos) const override; + virtual void ComputeAttractHeading(int qid, float& heading) const override; + + CPedShelterAttractor(C2dEffect* pEffect, const CMatrix& matrix, int32 maxpeds, float qdist, float waitTime, float approachTime, float distance, float headingdiff, float posdisp, float headdisp) : + CPedAttractor(pEffect, matrix, maxpeds, qdist, waitTime, approachTime, distance, headingdiff, posdisp, headdisp) + {}; + + + CVector GetDisplacement(int32 qid) const; +}; + +class CPedStopAttractor : public CPedAttractor +{ +public: + virtual ePedAttractorType GetType() const override { return ATTRACTOR_STOP; } + virtual void UpdatePedStateOnDeparture(CPed* pPed) const override {}; + + CPedStopAttractor(C2dEffect* pEffect, const CMatrix& matrix, int32 maxpeds, float qdist, float waitTime, float approachTime, float distance, float headingdiff, float posdisp, float headdisp) : + CPedAttractor(pEffect, matrix, maxpeds, qdist, waitTime, approachTime, distance, headingdiff, posdisp, headdisp) + {}; +}; \ No newline at end of file diff --git a/src/peds/PedIK.cpp b/src/peds/PedIK.cpp index 8b3835b3..2925667a 100644 --- a/src/peds/PedIK.cpp +++ b/src/peds/PedIK.cpp @@ -7,7 +7,7 @@ #include "General.h" #include "RwHelper.h" -//--MIAMI: file almost done (only some special weapon cases left) +//--MIAMI: file done LimbMovementInfo CPedIK::ms_torsoInfo = { DEGTORAD(50.0f), DEGTORAD(-50.0f), DEGTORAD(8.0f), DEGTORAD(45.0f), DEGTORAD(-45.0f), DEGTORAD(5.0f) }; LimbMovementInfo CPedIK::ms_headInfo = { DEGTORAD(90.0f), DEGTORAD(-90.0f), DEGTORAD(15.0f), DEGTORAD(45.0f), DEGTORAD(-45.0f), DEGTORAD(8.0f) }; @@ -57,9 +57,9 @@ CPedIK::RotateTorso(AnimBlendFrameData *node, LimbOrientation *limb, bool change } void -CPedIK::GetComponentPosition(RwV3d *pos, uint32 node) +CPedIK::GetComponentPosition(RwV3d &pos, uint32 node) { - *pos = GetComponentMatrix(m_ped, node)->pos; + pos = GetComponentMatrix(m_ped, node)->pos; } LimbMoveStatus @@ -292,10 +292,20 @@ CPedIK::PointGunInDirectionUsingArm(float targetYaw, float targetPitch) bool CPedIK::PointGunAtPosition(CVector const& position) { - // TODO(MIAMI): special cases for some weapons + CVector startPoint; + if (m_ped->GetWeapon()->m_eWeaponType == WEAPONTYPE_SPAS12_SHOTGUN || m_ped->GetWeapon()->m_eWeaponType == WEAPONTYPE_STUBBY_SHOTGUN) + startPoint = m_ped->GetPosition(); + else { + RwV3d armPos; + GetComponentPosition(armPos, PED_UPPERARMR); + startPoint.x = m_ped->GetPosition().x; + startPoint.y = m_ped->GetPosition().y; + startPoint.z = armPos.z; + } + return PointGunInDirection( - CGeneral::GetRadianAngleBetweenPoints(position.x, position.y, m_ped->GetPosition().x, m_ped->GetPosition().y), - CGeneral::GetRadianAngleBetweenPoints(position.z, Distance2D(m_ped->GetPosition(), position.x, position.y), m_ped->GetPosition().z, 0.0f)); + CGeneral::GetRadianAngleBetweenPoints(position.x, position.y, startPoint.x, startPoint.y), + CGeneral::GetRadianAngleBetweenPoints(position.z, Distance2D(m_ped->GetPosition(), position.x, position.y), startPoint.z, 0.0f)); } bool diff --git a/src/peds/PedIK.h b/src/peds/PedIK.h index b5f895cd..ee719fea 100644 --- a/src/peds/PedIK.h +++ b/src/peds/PedIK.h @@ -51,7 +51,7 @@ public: bool PointGunInDirection(float targetYaw, float targetPitch); bool PointGunInDirectionUsingArm(float targetYaw, float targetPitch); bool PointGunAtPosition(CVector const& position); - void GetComponentPosition(RwV3d *pos, uint32 node); + void GetComponentPosition(RwV3d &pos, uint32 node); void RotateTorso(AnimBlendFrameData* animBlend, LimbOrientation* limb, bool changeRoll); void ExtractYawAndPitchLocal(RwMatrix *mat, float *yaw, float *pitch); void ExtractYawAndPitchLocalSkinned(AnimBlendFrameData *node, float *yaw, float *pitch); diff --git a/src/peds/PlayerPed.cpp b/src/peds/PlayerPed.cpp index 04251860..aafb80c7 100644 --- a/src/peds/PlayerPed.cpp +++ b/src/peds/PlayerPed.cpp @@ -47,19 +47,12 @@ CPlayerPed::CPlayerPed(void) : CPed(PEDTYPE_PLAYER1) m_nSpeedTimer = 0; m_bSpeedTimerFlag = false; - // This should be something inlined // TODO(Miami) - // if (pPointGunAt) // m_pPointGunAt->CleanUpOldReference(&m_pPointGunAt); + m_pPointGunAt = nil; - if (m_nPedState == PED_FOLLOW_PATH) - ClearFollowPath(); - - // TODO(Miami) - // This should be something inlined - - m_nPedState = PED_IDLE; + SetPedState(PED_IDLE); m_fMaxStamina = 150.0f; m_fCurrentStamina = m_fMaxStamina; m_fStaminaProgress = 0.0f; @@ -92,6 +85,11 @@ CPlayerPed::CPlayerPed(void) : CPed(PEDTYPE_PLAYER1) void CPlayerPed::ClearWeaponTarget() { if (m_nPedType == PEDTYPE_PLAYER1) { + + // TODO(Miami) + // if (m_pPointGunAt) + // m_pPointGunAt->CleanUpOldReference(&m_pPointGunAt); + m_pPointGunAt = nil; TheCamera.ClearPlayerWeaponMode(); CWeaponEffects::ClearCrossHair(); @@ -213,13 +211,15 @@ CPlayerPed::MakeChangesForNewWeapon(eWeaponType weapon) TheCamera.ClearPlayerWeaponMode(); } SetCurrentWeapon(weapon); + m_nSelectedWepSlot = m_currentWeapon; GetWeapon()->m_nAmmoInClip = Min(GetWeapon()->m_nAmmoTotal, CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType)->m_nAmountofAmmunition); if (!(CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType)->m_bCanAim)) ClearWeaponTarget(); - CAnimBlendAssociation* weaponAnim = RpAnimBlendClumpGetAssociation(GetClump(), CWeaponInfo::GetWeaponInfo(WEAPONTYPE_SNIPERRIFLE)->m_bAnimDetonate ? 62 : 205); + // WEAPONTYPE_SNIPERRIFLE? Wut? + CAnimBlendAssociation* weaponAnim = RpAnimBlendClumpGetAssociation(GetClump(), GetPrimaryFireAnim(CWeaponInfo::GetWeaponInfo(WEAPONTYPE_SNIPERRIFLE))); if (weaponAnim) { weaponAnim->SetRun(); weaponAnim->flags |= ASSOC_FADEOUTWHENDONE; @@ -283,10 +283,7 @@ CPlayerPed::SetInitialState(void) m_pFire->Extinguish(); RpAnimBlendClumpRemoveAllAssociations(GetClump()); - if (m_nPedState == PED_FOLLOW_PATH) - ClearFollowPath(); - - m_nPedState = PED_IDLE; + SetPedState(PED_IDLE); SetMoveState(PEDMOVE_STILL); m_nLastPedState = PED_NONE; m_animGroup = ASSOCGRP_PLAYER; @@ -444,7 +441,7 @@ CPlayerPed::SetRealMoveAnim(void) } else if (curSprintAssoc->blendDelta >= 0.0f || curSprintAssoc->blendAmount >= 0.8f) { if (m_fMoveSpeed < 0.4f) { AnimationId runStopAnim; - if (curSprintAssoc->currentTime / curSprintAssoc->hierarchy->totalLength < 0.5) // double + if (curSprintAssoc->GetProgress() < 0.5) // double runStopAnim = ANIM_RUN_STOP; else runStopAnim = ANIM_RUN_STOP_R; @@ -539,6 +536,8 @@ CPlayerPed::RestoreSprintEnergy(float restoreSpeed) m_fCurrentStamina += restoreSpeed * CTimer::GetTimeStep() * 0.5f; } + +// TODO(Miami) bool CPlayerPed::DoWeaponSmoothSpray(void) { @@ -546,7 +545,7 @@ CPlayerPed::DoWeaponSmoothSpray(void) eWeaponType weapon = GetWeapon()->m_eWeaponType; if (weapon == WEAPONTYPE_FLAMETHROWER || weapon == WEAPONTYPE_COLT45 || weapon == WEAPONTYPE_UZI || weapon == WEAPONTYPE_TEC9 || weapon == WEAPONTYPE_SILENCED_INGRAM || weapon == WEAPONTYPE_MP5 || - weapon == WEAPONTYPE_SHOTGUN || weapon == WEAPONTYPE_AK47 || weapon == WEAPONTYPE_M16 || weapon == WEAPONTYPE_HELICANNON) + weapon == WEAPONTYPE_SHOTGUN || weapon == WEAPONTYPE_RUGER || weapon == WEAPONTYPE_M4 || weapon == WEAPONTYPE_HELICANNON) return true; } return false; @@ -567,7 +566,7 @@ CPlayerPed::DoesTargetHaveToBeBroken(CVector target, CWeapon *weaponUsed) if (distVec.Magnitude() > CWeaponInfo::GetWeaponInfo(weaponUsed->m_eWeaponType)->m_fRange) return true; - if (weaponUsed->m_eWeaponType != WEAPONTYPE_SHOTGUN && weaponUsed->m_eWeaponType != WEAPONTYPE_AK47) + if (weaponUsed->m_eWeaponType != WEAPONTYPE_SHOTGUN && weaponUsed->m_eWeaponType != WEAPONTYPE_RUGER) return false; distVec.Normalise(); @@ -631,7 +630,7 @@ CPlayerPed::PlayerControlSniper(CPad *padUsed) firePos = GetMatrix() * firePos; GetWeapon()->Fire(this, &firePos); } - GetWeapon()->Update(m_audioEntityId); + GetWeapon()->Update(m_audioEntityId, nil); } // --MIAMI: Made compatible with slots, but still TODO @@ -666,7 +665,10 @@ CPlayerPed::ProcessWeaponSwitch(CPad *padUsed) for (m_nSelectedWepSlot = m_currentWeapon - 1; ; --m_nSelectedWepSlot) { if (m_nSelectedWepSlot < 0) - m_nSelectedWepSlot = 9; + m_nSelectedWepSlot = TOTAL_WEAPON_SLOTS - 1; + + if (m_nSelectedWepSlot == 0) + break; if (HasWeaponSlot(m_nSelectedWepSlot) && GetWeapon(m_nSelectedWepSlot).HasWeaponAmmoToBeUsed()) { break; @@ -678,7 +680,7 @@ CPlayerPed::ProcessWeaponSwitch(CPad *padUsed) spentAmmoCheck: if (CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType)->m_eWeaponFire != WEAPON_FIRE_MELEE - /*&& (!padUsed->GetWeapon() || GetWeapon()->m_eWeaponType != WEAPONTYPE_MINIGUN) */) { + && (!padUsed->GetWeapon() || GetWeapon()->m_eWeaponType != WEAPONTYPE_MINIGUN)) { if (GetWeapon()->m_nAmmoTotal <= 0) { if (TheCamera.PlayerWeaponMode.Mode != CCam::MODE_M16_1STPERSON && TheCamera.PlayerWeaponMode.Mode != CCam::MODE_SNIPER @@ -690,11 +692,16 @@ spentAmmoCheck: else m_nSelectedWepSlot = 2; - // BUG: m_nSelectedWepSlot is slot in VC but they compared against weapon types, lol. for (; m_nSelectedWepSlot >= 0; --m_nSelectedWepSlot) { - if (m_nSelectedWepSlot == WEAPONTYPE_BASEBALLBAT && GetWeapon(6).m_eWeaponType == WEAPONTYPE_BASEBALLBAT + + // BUG: m_nSelectedWepSlot and GetWeapon(..) takes slot in VC but they compared them against weapon types in whole condition! jeez +#ifdef FIX_BUGS + if (m_nSelectedWepSlot == 1 || GetWeapon(m_nSelectedWepSlot).m_nAmmoTotal > 0 && m_nSelectedWepSlot != 2) { +#else + if (m_nSelectedWepSlot == WEAPONTYPE_BASEBALLBAT && GetWeapon(WEAPONTYPE_BASEBALLBAT).m_eWeaponType == WEAPONTYPE_BASEBALLBAT || GetWeapon(m_nSelectedWepSlot).m_nAmmoTotal > 0 - /*&& m_nSelectedWepSlot != WEAPONTYPE_MOLOTOV && m_nSelectedWepSlot != WEAPONTYPE_GRENADE && m_nSelectedWepSlot != WEAPONTYPE_TEARGAS */) { + && m_nSelectedWepSlot != WEAPONTYPE_MOLOTOV && m_nSelectedWepSlot != WEAPONTYPE_GRENADE && m_nSelectedWepSlot != WEAPONTYPE_TEARGAS) { +#endif goto switchDetectDone; } } @@ -727,7 +734,7 @@ CPlayerPed::PlayerControlM16(CPad *padUsed) firePos = GetMatrix() * firePos; GetWeapon()->Fire(this, &firePos); } - GetWeapon()->Update(m_audioEntityId); + GetWeapon()->Update(m_audioEntityId, nil); } void @@ -1011,18 +1018,18 @@ CPlayerPed::ProcessAnimGroups(void) if (m_fWalkAngle > 0.0f) { if (GetWeapon()->m_eWeaponType == WEAPONTYPE_ROCKETLAUNCHER) groupToSet = ASSOCGRP_ROCKETLEFT; - else if (/*GetWeapon()->m_eWeaponType == WEAPONTYPE_CHAINSAW || */ - GetWeapon()->m_eWeaponType == WEAPONTYPE_FLAMETHROWER - /* || GetWeapon()->m_eWeaponType == WEAPONTYPE_MINIGUN*/ ) + else if (GetWeapon()->m_eWeaponType == WEAPONTYPE_CHAINSAW || + GetWeapon()->m_eWeaponType == WEAPONTYPE_FLAMETHROWER || + GetWeapon()->m_eWeaponType == WEAPONTYPE_MINIGUN) groupToSet = ASSOCGRP_CHAINSAWLEFT; else groupToSet = ASSOCGRP_PLAYERLEFT; } else { if (GetWeapon()->m_eWeaponType == WEAPONTYPE_ROCKETLAUNCHER) groupToSet = ASSOCGRP_ROCKETRIGHT; - else if (/*GetWeapon()->m_eWeaponType == WEAPONTYPE_CHAINSAW || */ - GetWeapon()->m_eWeaponType == WEAPONTYPE_FLAMETHROWER - /* || GetWeapon()->m_eWeaponType == WEAPONTYPE_MINIGUN*/) + else if (GetWeapon()->m_eWeaponType == WEAPONTYPE_CHAINSAW || + GetWeapon()->m_eWeaponType == WEAPONTYPE_FLAMETHROWER || + GetWeapon()->m_eWeaponType == WEAPONTYPE_MINIGUN) groupToSet = ASSOCGRP_CHAINSAWRIGHT; else groupToSet = ASSOCGRP_PLAYERRIGHT; @@ -1030,9 +1037,9 @@ CPlayerPed::ProcessAnimGroups(void) } else { if (GetWeapon()->m_eWeaponType == WEAPONTYPE_ROCKETLAUNCHER) groupToSet = ASSOCGRP_ROCKETBACK; - else if (/*GetWeapon()->m_eWeaponType == WEAPONTYPE_CHAINSAW || */ - GetWeapon()->m_eWeaponType == WEAPONTYPE_FLAMETHROWER - /* || GetWeapon()->m_eWeaponType == WEAPONTYPE_MINIGUN*/) + else if (GetWeapon()->m_eWeaponType == WEAPONTYPE_CHAINSAW || + GetWeapon()->m_eWeaponType == WEAPONTYPE_FLAMETHROWER || + GetWeapon()->m_eWeaponType == WEAPONTYPE_MINIGUN) groupToSet = ASSOCGRP_CHAINSAWBACK; else groupToSet = ASSOCGRP_PLAYERBACK; @@ -1042,20 +1049,18 @@ CPlayerPed::ProcessAnimGroups(void) groupToSet = ASSOCGRP_PLAYERROCKET; } else { if (GetWeapon()->m_eWeaponType == WEAPONTYPE_BASEBALLBAT - /* || GetWeapon()->m_eWeaponType == WEAPONTYPE_MACHETE */) + || GetWeapon()->m_eWeaponType == WEAPONTYPE_MACHETE) groupToSet = ASSOCGRP_PLAYERBBBAT; - else if (/*GetWeapon()->m_eWeaponType == WEAPONTYPE_CHAINSAW || */ - GetWeapon()->m_eWeaponType == WEAPONTYPE_FLAMETHROWER - /* || GetWeapon()->m_eWeaponType == WEAPONTYPE_MINIGUN*/) + else if (GetWeapon()->m_eWeaponType == WEAPONTYPE_CHAINSAW || + GetWeapon()->m_eWeaponType == WEAPONTYPE_FLAMETHROWER || + GetWeapon()->m_eWeaponType == WEAPONTYPE_MINIGUN) groupToSet = ASSOCGRP_PLAYERCHAINSAW; else if (GetWeapon()->m_eWeaponType != WEAPONTYPE_COLT45 && GetWeapon()->m_eWeaponType != WEAPONTYPE_UZI - // I hope this was inlined... - /* - && GetWeapon()->m_eWeaponType != WEAPONTYPE_PYTHON*/ && GetWeapon()->m_eWeaponType != WEAPONTYPE_TEC9 - && GetWeapon()->m_eWeaponType != WEAPONTYPE_SILENCED_INGRAM && GetWeapon()->m_eWeaponType != WEAPONTYPE_MP5 /* + // I hope this is a inlined function... + && GetWeapon()->m_eWeaponType != WEAPONTYPE_PYTHON && GetWeapon()->m_eWeaponType != WEAPONTYPE_TEC9 + && GetWeapon()->m_eWeaponType != WEAPONTYPE_SILENCED_INGRAM && GetWeapon()->m_eWeaponType != WEAPONTYPE_MP5 && GetWeapon()->m_eWeaponType != WEAPONTYPE_GOLFCLUB && GetWeapon()->m_eWeaponType != WEAPONTYPE_KATANA - && GetWeapon()->m_eWeaponType != WEAPONTYPE_CAMERA - */) { + && GetWeapon()->m_eWeaponType != WEAPONTYPE_CAMERA) { if (!GetWeapon()->IsType2Handed()) { groupToSet = ASSOCGRP_PLAYER; } else { @@ -1073,6 +1078,7 @@ CPlayerPed::ProcessAnimGroups(void) } } +// TODO(Miami): Hella TODO void CPlayerPed::ProcessPlayerWeapon(CPad *padUsed) { @@ -1084,8 +1090,9 @@ CPlayerPed::ProcessPlayerWeapon(CPad *padUsed) } if (!m_pFire) { if (GetWeapon()->m_eWeaponType == WEAPONTYPE_ROCKETLAUNCHER || - GetWeapon()->m_eWeaponType == WEAPONTYPE_SNIPERRIFLE || GetWeapon()->m_eWeaponType == WEAPONTYPE_M16) { - if (padUsed->TargetJustDown()) { + GetWeapon()->m_eWeaponType == WEAPONTYPE_SNIPERRIFLE || GetWeapon()->m_eWeaponType == WEAPONTYPE_M4 || + GetWeapon()->m_eWeaponType == WEAPONTYPE_RUGER) { + if (padUsed->TargetJustDown()/* || TheCamera.m_bAllow1rstPersonWeaponsCamera */) { // TODO(Miami): Cam SetStoredState(); m_nPedState = PED_SNIPER_MODE; #ifdef FREE_CAM @@ -1119,7 +1126,7 @@ CPlayerPed::ProcessPlayerWeapon(CPad *padUsed) else #endif SetAttack(m_pPointGunAt); - } else if (m_currentWeapon != WEAPONTYPE_UNARMED) { + } else { if (m_nPedState == PED_ATTACK) { if (padUsed->WeaponJustDown()) { m_bHaveTargetSelected = true; @@ -1130,12 +1137,19 @@ CPlayerPed::ProcessPlayerWeapon(CPad *padUsed) m_fAttackButtonCounter = 0.0f; m_bHaveTargetSelected = false; } - SetAttack(nil); - } else if (padUsed->WeaponJustDown()) { - if (m_fMoveSpeed < 1.0f) - StartFightAttack(padUsed->GetWeapon()); - else - SetAttack(nil); + if (GetWeapon()->m_eWeaponType != WEAPONTYPE_UNARMED && GetWeapon()->m_eWeaponType != WEAPONTYPE_BRASSKNUCKLE && + !weaponInfo->m_bFightMode) { + + if (GetWeapon()->m_eWeaponType != WEAPONTYPE_DETONATOR && GetWeapon()->m_eWeaponType != WEAPONTYPE_DETONATOR_GRENADE || + padUsed->WeaponJustDown()) + + SetAttack(nil); + } else if (padUsed->WeaponJustDown()) { + if (m_fMoveSpeed < 1.0f || m_nPedState == PED_FIGHT) + StartFightAttack(padUsed->GetWeapon()); + else + SetAttack(nil); + } } } } else { @@ -1152,7 +1166,7 @@ CPlayerPed::ProcessPlayerWeapon(CPad *padUsed) m_nSelectedWepSlot == m_currentWeapon && m_nMoveState != PEDMOVE_SPRINT) { // Weapons except throwable and melee ones - if (weaponInfo->m_bCanAim || weaponInfo->m_b1stPerson || weaponInfo->m_bExpands) { + if (weaponInfo->m_nWeaponSlot > 2) { if ((padUsed->GetTarget() && weaponInfo->m_bCanAimWithArm) || padUsed->GetWeapon()) { float limitedCam = CGeneral::LimitRadianAngle(-TheCamera.Orientation); @@ -1170,7 +1184,7 @@ CPlayerPed::ProcessPlayerWeapon(CPad *padUsed) #endif } else { m_fRotationDest = limitedCam; - m_headingRate = 50.0f; + m_headingRate = 12.5f; // Anim. fix for shotgun, ak47 and m16 (we must finish rot. it quickly) if (weaponInfo->m_bCanAim && padUsed->WeaponJustDown()) { @@ -1225,7 +1239,7 @@ CPlayerPed::ProcessPlayerWeapon(CPad *padUsed) #else else if (weaponInfo->m_bCanAim && !CCamera::m_bUseMouse3rdPerson) { #endif - if (padUsed->TargetJustDown()) + if (padUsed->TargetJustDown()/* || TheCamera.m_bAllow1rstPersonWeaponsCamera */) // TODO(Miami): Cam FindWeaponLockOnTarget(); } } else if (m_pPointGunAt) { @@ -1238,7 +1252,7 @@ CPlayerPed::ProcessPlayerWeapon(CPad *padUsed) #else CVector markPos; if (m_pPointGunAt->IsPed()) { - ((CPed*)m_pPointGunAt)->m_pedIK.GetComponentPosition((RwV3d*)markPos, PED_MID); + ((CPed*)m_pPointGunAt)->m_pedIK.GetComponentPosition(*(RwV3d *)&markPos, PED_MID); } else { markPos = m_pPointGunAt->GetPosition(); } @@ -1491,7 +1505,7 @@ CPlayerPed::ProcessControl(void) } break; case PED_SNIPER_MODE: - if (FindPlayerPed()->GetWeapon()->m_eWeaponType == WEAPONTYPE_M16) { + if (FindPlayerPed()->GetWeapon()->m_eWeaponType == WEAPONTYPE_M4) { if (padUsed) PlayerControlM16(padUsed); } else if (padUsed) { @@ -1546,7 +1560,7 @@ CPlayerPed::ProcessControl(void) } if (padUsed && IsPedShootable()) { ProcessWeaponSwitch(padUsed); - GetWeapon()->Update(m_audioEntityId); + GetWeapon()->Update(m_audioEntityId, this); } ProcessAnimGroups(); if (padUsed) { @@ -1601,6 +1615,21 @@ CPlayerPed::ProcessControl(void) #endif } +bool +CPlayerPed::DoesPlayerWantNewWeapon(eWeaponType weapon, bool onlyIfSlotIsEmpty) +{ + uint32 slot = CWeaponInfo::GetWeaponInfo(weapon)->m_nWeaponSlot; + + if (!HasWeaponSlot(slot) || GetWeapon(slot).m_eWeaponType == weapon) + return true; + + if (onlyIfSlotIsEmpty) + return false; + + // Check if he's using that slot right now. + return m_nPedState != PED_ATTACK && m_nPedState != PED_AIM_GUN || slot != m_currentWeapon; +} + #ifdef COMPATIBLE_SAVES #define CopyFromBuf(buf, data) memcpy(&data, buf, sizeof(data)); SkipSaveBuf(buf, sizeof(data)); #define CopyToBuf(buf, data) memcpy(buf, &data, sizeof(data)); SkipSaveBuf(buf, sizeof(data)); diff --git a/src/peds/PlayerPed.h b/src/peds/PlayerPed.h index 354140df..1042fe16 100644 --- a/src/peds/PlayerPed.h +++ b/src/peds/PlayerPed.h @@ -82,6 +82,7 @@ public: void ProcessAnimGroups(void); void ProcessPlayerWeapon(CPad*); void PlayerControlZelda(CPad*); + bool DoesPlayerWantNewWeapon(eWeaponType, bool); static void SetupPlayerPed(int32); static void DeactivatePlayerPed(int32); diff --git a/src/peds/Population.cpp b/src/peds/Population.cpp index 14bd042c..40ceb6c3 100644 --- a/src/peds/Population.cpp +++ b/src/peds/Population.cpp @@ -329,19 +329,7 @@ CPopulation::UpdatePedCount(ePedType pedType, bool decrease) int CPopulation::ChooseGangOccupation(int gangId) { - int8 modelOverride = CGangs::GetGangPedModelOverride(gangId); - - // All gangs have 2 models - int firstGangModel = 2 * gangId + MI_GANG01; - - // GetRandomNumberInRange never returns max. value - if (modelOverride == -1) - return CGeneral::GetRandomNumberInRange(firstGangModel, firstGangModel + 2); - - if (modelOverride != 0) - return firstGangModel + 1; - else - return firstGangModel; + return CGangs::ChooseGangPedModel(gangId); } //--MIAMI: done @@ -473,17 +461,16 @@ CPopulation::AddPed(ePedType pedType, uint32 miOrCopType, CVector const &coors, if (ms_bGivePedsWeapons) { eWeaponType weapon; - // TODO(Miami): Look here when weapons have been ported switch (CGeneral::GetRandomNumber() & 3) { case 0: weapon = WEAPONTYPE_COLT45; break; case 1: - //weapon = WEAPONTYPE_NIGHTSTICK; - //break; + weapon = WEAPONTYPE_NIGHTSTICK; + break; case 2: - //weapon = WEAPONTYPE_GOLFCLUB; - //break; + weapon = WEAPONTYPE_GOLFCLUB; + break; case 3: weapon = WEAPONTYPE_TEC9; break; @@ -734,7 +721,7 @@ CPopulation::AddToPopulation(float minDist, float maxDist, float minDistOffScree } CPed* -CPopulation::AddPedInCar(CVehicle* car, bool isPassenger) +CPopulation::AddPedInCar(CVehicle* car, bool isDriver) { int defaultModel = MI_MALE01; int miamiViceIndex = 0; @@ -777,7 +764,7 @@ CPopulation::AddPedInCar(CVehicle* car, bool isPassenger) case MI_VICECHEE: // TODO(MIAMI): figure out new structure of the function preferredModel = COP_MIAMIVICE; pedType = PEDTYPE_COP; - miamiViceIndex = (isPassenger ? 2 * CCarCtrl::MiamiViceCycle : 2 * CCarCtrl::MiamiViceCycle + 1); + miamiViceIndex = (isDriver ? 2 * CCarCtrl::MiamiViceCycle : 2 * CCarCtrl::MiamiViceCycle + 1); break; case MI_TAXI: case MI_CABBIE: @@ -828,29 +815,11 @@ CPopulation::AddPedInCar(CVehicle* car, bool isPassenger) CPed *newPed = CPopulation::AddPed((ePedType)pedType, preferredModel, car->GetPosition(), miamiViceIndex); newPed->bUsesCollision = false; - // what?? - if (pedType != PEDTYPE_COP) { - newPed->SetCurrentWeapon(WEAPONTYPE_COLT45); + if (newPed->GetWeapon()->m_eWeaponType != WEAPONTYPE_UNARMED) { newPed->RemoveWeaponModel(CWeaponInfo::GetWeaponInfo(newPed->GetWeapon()->m_eWeaponType)->m_nModelId); } - /* - // Miami leftover - if (car->m_vehType == VEHICLE_TYPE_BIKE) { - newPed->m_pVehicleAnim = CAnimManager::BlendAnimation(newPed->GetClump(), ASSOCGRP_STD, *((CBike*)car + 308h), 100.0f); - } else */ - // FIX: Make peds comfortable while driving car/boat -#ifdef FIX_BUGS - { - newPed->m_pVehicleAnim = CAnimManager::BlendAnimation(newPed->GetClump(), ASSOCGRP_STD, car->GetDriverAnim(), 100.0f); - } -#else - { - newPed->m_pVehicleAnim = CAnimManager::BlendAnimation(newPed->GetClump(), ASSOCGRP_STD, ANIM_CAR_SIT, 100.0f); - } -#endif - - newPed->StopNonPartialAnims(); + newPed->AddInCarAnims(car, isDriver); return newPed; } @@ -883,18 +852,12 @@ CPopulation::ConvertToRealObject(CDummyObject *dummy) if (!obj) return; - bool makeInvisible; CWorld::Remove(dummy); delete dummy; CWorld::Add(obj); - int16 mi = obj->GetModelIndex(); - if (mi == MI_GLASS1 || mi == MI_GLASS2 || mi == MI_GLASS3 || mi == MI_GLASS4 || - mi == MI_GLASS5 || mi == MI_GLASS6 || mi == MI_GLASS7 || mi == MI_GLASS8) - makeInvisible = true; - else - makeInvisible = false; - if (makeInvisible) { + CSimpleModelInfo *mi = (CSimpleModelInfo*)CModelInfo::GetModelInfo(obj->GetModelIndex()); + if (IsGlass(obj->GetModelIndex()) && !mi->m_isArtistGlass) { obj->bIsVisible = false; } else if (obj->GetModelIndex() == MI_BUOY) { obj->bIsStatic = false; @@ -913,17 +876,9 @@ CPopulation::ConvertToDummyObject(CObject *obj) dummy->GetMatrix().UpdateRW(); dummy->UpdateRwFrame(); - bool makeInvisible; - int16 mi = obj->GetModelIndex(); - if (mi == MI_GLASS1 || mi == MI_GLASS2 || mi == MI_GLASS3 || mi == MI_GLASS4 || - mi == MI_GLASS5 || mi == MI_GLASS6 || mi == MI_GLASS7 || mi == MI_GLASS8) - makeInvisible = true; - else - makeInvisible = false; - - if (makeInvisible) { + CSimpleModelInfo *mi = (CSimpleModelInfo*)CModelInfo::GetModelInfo(obj->GetModelIndex()); + if (IsGlass(obj->GetModelIndex()) && !mi->m_isArtistGlass) dummy->bIsVisible = false; - } CWorld::Remove(obj); delete obj; @@ -1123,7 +1078,7 @@ CPopulation::AddDeadPedInFrontOfCar(const CVector& pos, CVehicle* pCulprit) return nil; CPed* pPed = CPopulation::AddPed(PEDTYPE_CIVMALE, MI_MALE01, pos); // TODO(MIAMI): 4th parameter pPed->SetDie(ANIM_KO_SHOT_FRONT1, 4.0f, 0.0f); - //TODO(MIAMI): set money == 0 + pPed->m_nPedMoney = 0; pPed->bDeadPedInFrontOfCar = true; pPed->m_vehicleInAccident = pCulprit; pCulprit->RegisterReference((CEntity**)&pPed->m_vehicleInAccident); @@ -1137,7 +1092,7 @@ CPopulation::AddDeadPedInFrontOfCar(const CVector& pos, CVehicle* pCulprit) } } } - CColPoint colpts[32]; + CColPoint colpts[MAX_COLLISION_POINTS]; if (CCollision::ProcessColModels(pCulprit->GetMatrix(), *pCulprit->GetColModel(), pPed->GetMatrix(), *pPed->GetColModel(), colpts, nil, nil)) { CWorld::Remove(pPed); delete pPed; diff --git a/src/peds/Population.h b/src/peds/Population.h index 20d6e567..ae4aa44c 100644 --- a/src/peds/Population.h +++ b/src/peds/Population.h @@ -70,7 +70,7 @@ public: static void LoadPedGroups(); static void UpdatePedCount(ePedType, bool); static void DealWithZoneChange(eLevelName oldLevel, eLevelName newLevel, bool); - static CPed *AddPedInCar(CVehicle *car, bool isPassenger); + static CPed *AddPedInCar(CVehicle *car, bool isDriver); static bool IsPointInSafeZone(CVector *coors); static void RemovePed(CPed *ent); static int32 ChooseCivilianOccupation(int32); diff --git a/src/render/2dEffect.h b/src/render/2dEffect.h index 2a71a8d5..504824c5 100644 --- a/src/render/2dEffect.h +++ b/src/render/2dEffect.h @@ -3,7 +3,9 @@ enum { EFFECT_LIGHT, EFFECT_PARTICLE, - EFFECT_ATTRACTOR + EFFECT_ATTRACTOR, + EFFECT_PED_ATTRACTOR, + EFFECT_SUNGLARE }; enum { @@ -34,6 +36,8 @@ enum { // same order as CPointLights flags, must start at 2 LIGHTFLAG_FOG_NORMAL = 2, // can have light and fog LIGHTFLAG_FOG_ALWAYS = 4, // fog only + LIGHTFLAG_HIDE_OBJECT = 8, // hide the object instead of rendering light (???) + LIGHTFLAG_LONG_DIST = 16, LIGHTFLAG_FOG = (LIGHTFLAG_FOG_NORMAL|LIGHTFLAG_FOG_ALWAYS) }; @@ -63,6 +67,11 @@ public: uint8 flags; uint8 probability; }; + struct PedAttractor { + CVector queueDir; + CVector useDir; + int8 type; + }; CVector pos; CRGBA col; @@ -71,6 +80,7 @@ public: Light light; Particle particle; Attractor attractor; + PedAttractor pedattr; }; C2dEffect(void) {} diff --git a/src/render/Clouds.cpp b/src/render/Clouds.cpp index 9cd3b5d2..c6ba0f10 100644 --- a/src/render/Clouds.cpp +++ b/src/render/Clouds.cpp @@ -62,8 +62,13 @@ void CClouds::Update(void) { float s = Sin(TheCamera.Orientation - 0.85f); +#ifdef FIX_BUGS + CloudRotation += CWeather::Wind*s*0.001f*CTimer::GetTimeStepFix(); + IndividualRotation += (CWeather::Wind*CTimer::GetTimeStep()*0.5f + 0.3f*CTimer::GetTimeStepFix()) * 60.0f; +#else CloudRotation += CWeather::Wind*s*0.001f; IndividualRotation += (CWeather::Wind*CTimer::GetTimeStep()*0.5f + 0.3f) * 60.0f; +#endif } void diff --git a/src/render/Coronas.cpp b/src/render/Coronas.cpp index e36bdf3d..efe486fe 100644 --- a/src/render/Coronas.cpp +++ b/src/render/Coronas.cpp @@ -129,7 +129,8 @@ CCoronas::Update(void) void CCoronas::RegisterCorona(uint32 id, uint8 red, uint8 green, uint8 blue, uint8 alpha, const CVector &coors, float size, float drawDist, RwTexture *tex, - int8 flareType, uint8 reflection, uint8 LOScheck, uint8 drawStreak, float someAngle) + int8 flareType, uint8 reflection, uint8 LOScheck, uint8 drawStreak, float someAngle, + bool longDist, float nearDist) { int i; @@ -192,11 +193,13 @@ CCoronas::RegisterCorona(uint32 id, uint8 red, uint8 green, uint8 blue, uint8 al void CCoronas::RegisterCorona(uint32 id, uint8 red, uint8 green, uint8 blue, uint8 alpha, - const CVector &coors, float size, float drawDist, uint8 type, - int8 flareType, uint8 reflection, uint8 LOScheck, uint8 drawStreak, float someAngle) + const CVector &coors, float size, float drawDist, uint8 type, + int8 flareType, uint8 reflection, uint8 LOScheck, uint8 drawStreak, float someAngle, + bool longDist, float nearDist) { RegisterCorona(id, red, green, blue, alpha, coors, size, drawDist, - gpCoronaTexture[type], flareType, reflection, LOScheck, drawStreak, someAngle); + gpCoronaTexture[type], flareType, reflection, LOScheck, drawStreak, someAngle, + longDist, nearDist); } void @@ -506,18 +509,18 @@ CCoronas::DoSunAndMoon(void) { // yeah, moon is done somewhere else.... - CVector sunCoors = CTimeCycle::GetSunPosition(); + CVector sunCoors = CTimeCycle::GetSunDirection(); sunCoors *= 150.0f; sunCoors += TheCamera.GetPosition(); - if(CTimeCycle::GetSunPosition().z > -0.2f){ + if(CTimeCycle::GetSunDirection().z > -0.2f){ float size = ((CGeneral::GetRandomNumber()&0xFF) * 0.005f + 10.0f) * CTimeCycle::GetSunSize(); RegisterCorona(SUN_CORE, CTimeCycle::GetSunCoreRed(), CTimeCycle::GetSunCoreGreen(), CTimeCycle::GetSunCoreBlue(), 255, sunCoors, size, 999999.88f, TYPE_STAR, FLARE_NONE, REFLECTION_OFF, LOSCHECK_OFF, STREAK_OFF, 0.0f); - if(CTimeCycle::GetSunPosition().z > 0.0f) + if(CTimeCycle::GetSunDirection().z > 0.0f) RegisterCorona(SUN_CORONA, CTimeCycle::GetSunCoronaRed(), CTimeCycle::GetSunCoronaGreen(), CTimeCycle::GetSunCoronaBlue(), 255, sunCoors, 25.0f * CTimeCycle::GetSunSize(), diff --git a/src/render/Coronas.h b/src/render/Coronas.h index 70e9ccd5..cb4e8583 100644 --- a/src/render/Coronas.h +++ b/src/render/Coronas.h @@ -90,10 +90,12 @@ public: static void Update(void); static void RegisterCorona(uint32 id, uint8 red, uint8 green, uint8 blue, uint8 alpha, const CVector &coors, float size, float drawDist, RwTexture *tex, - int8 flareType, uint8 reflection, uint8 LOScheck, uint8 drawStreak, float someAngle); + int8 flareType, uint8 reflection, uint8 LOScheck, uint8 drawStreak, float someAngle, + bool longDist = false, float nearClip = 1.5f); static void RegisterCorona(uint32 id, uint8 red, uint8 green, uint8 blue, uint8 alpha, const CVector &coors, float size, float drawDist, uint8 type, - int8 flareType, uint8 reflection, uint8 LOScheck, uint8 drawStreak, float someAngle); + int8 flareType, uint8 reflection, uint8 LOScheck, uint8 drawStreak, float someAngle, + bool longDist = false, float nearClip = 1.5f); static void UpdateCoronaCoors(uint32 id, const CVector &coors, float drawDist, float someAngle); static void Render(void); static void RenderReflections(void); diff --git a/src/render/Credits.cpp b/src/render/Credits.cpp index dc0b0252..60e69583 100644 --- a/src/render/Credits.cpp +++ b/src/render/Credits.cpp @@ -128,12 +128,12 @@ CCredits::Render(void) PrintCreditText(1.7f, 1.7f, TheText.Get("CRED040"), lineoffset, scrolloffset); PrintCreditSpace(2.0f, lineoffset); PrintCreditText(1.4f, 0.82f, TheText.Get("CRED041"), lineoffset, scrolloffset); - if(CMenuManager::m_PrefsLanguage == LANGUAGE_ITALIAN) + if(FrontEndMenuManager.m_PrefsLanguage == LANGUAGE_ITALIAN) PrintCreditSpace(1.5, lineoffset); PrintCreditText(1.7f, 1.7f, TheText.Get("CRED042"), lineoffset, scrolloffset); PrintCreditSpace(2.0f, lineoffset); PrintCreditText(1.7f, 1.0f, TheText.Get("CRED043"), lineoffset, scrolloffset); - if(CMenuManager::m_PrefsLanguage == LANGUAGE_ITALIAN) + if(FrontEndMenuManager.m_PrefsLanguage == LANGUAGE_ITALIAN) PrintCreditSpace(1.5, lineoffset); PrintCreditText(1.7f, 1.7f, TheText.Get("CRED044"), lineoffset, scrolloffset); PrintCreditSpace(2.0f, lineoffset); @@ -176,7 +176,7 @@ CCredits::Render(void) PrintCreditSpace(2.0f, lineoffset); PrintCreditSpace(2.0f, lineoffset); PrintCreditText(1.7f, 1.0f, TheText.Get("CRED061"), lineoffset, scrolloffset); - if(CMenuManager::m_PrefsLanguage == LANGUAGE_ITALIAN) + if(FrontEndMenuManager.m_PrefsLanguage == LANGUAGE_ITALIAN) PrintCreditSpace(1.5, lineoffset); PrintCreditText(1.7f, 1.7f, TheText.Get("CRED062"), lineoffset, scrolloffset); PrintCreditSpace(2.0f, lineoffset); @@ -191,7 +191,7 @@ CCredits::Render(void) PrintCreditText(1.7f, 1.7f, TheText.Get("CRED068"), lineoffset, scrolloffset); PrintCreditSpace(2.0f, lineoffset); PrintCreditText(1.7f, 1.0f, TheText.Get("CRED069"), lineoffset, scrolloffset); - if(CMenuManager::m_PrefsLanguage == LANGUAGE_ITALIAN) + if(FrontEndMenuManager.m_PrefsLanguage == LANGUAGE_ITALIAN) PrintCreditSpace(1.5, lineoffset); PrintCreditText(1.7f, 1.7f, TheText.Get("CRED070"), lineoffset, scrolloffset); PrintCreditSpace(2.0f, lineoffset); @@ -220,7 +220,7 @@ CCredits::Render(void) PrintCreditText(1.7f, 1.7f, TheText.Get("CRED262"), lineoffset, scrolloffset); PrintCreditSpace(2.0f, lineoffset); PrintCreditText(1.7f, 1.0f, TheText.Get("CRED085"), lineoffset, scrolloffset); - if(CMenuManager::m_PrefsLanguage == LANGUAGE_ITALIAN) + if(FrontEndMenuManager.m_PrefsLanguage == LANGUAGE_ITALIAN) PrintCreditSpace(1.5, lineoffset); PrintCreditText(1.7f, 1.7f, TheText.Get("CRED086"), lineoffset, scrolloffset); PrintCreditSpace(2.0f, lineoffset); @@ -265,76 +265,76 @@ CCredits::Render(void) PrintCreditText(1.0, 1.0, TheText.Get("CRED108"), lineoffset, scrolloffset); PrintCreditSpace(1.0, lineoffset); PrintCreditText(1.0, 1.0, TheText.Get("CRED109"), lineoffset, scrolloffset); - if(CMenuManager::m_PrefsLanguage == LANGUAGE_ITALIAN) + if(FrontEndMenuManager.m_PrefsLanguage == LANGUAGE_ITALIAN) PrintCreditSpace(1.0, lineoffset); PrintCreditText(1.0, 1.0, TheText.Get("CRED110"), lineoffset, scrolloffset); PrintCreditSpace(2.0f, lineoffset); PrintCreditText(1.7f, 1.0f, TheText.Get("CRED111"), lineoffset, scrolloffset); PrintCreditText(1.0, 1.0, TheText.Get("CRED112"), lineoffset, scrolloffset); - if(CMenuManager::m_PrefsLanguage == LANGUAGE_ITALIAN) + if(FrontEndMenuManager.m_PrefsLanguage == LANGUAGE_ITALIAN) PrintCreditSpace(1.0, lineoffset); PrintCreditText(1.0, 1.0, TheText.Get("CRED113"), lineoffset, scrolloffset); - if(CMenuManager::m_PrefsLanguage == LANGUAGE_ITALIAN) + if(FrontEndMenuManager.m_PrefsLanguage == LANGUAGE_ITALIAN) PrintCreditSpace(1.0, lineoffset); PrintCreditText(1.0, 1.0, TheText.Get("CRED114"), lineoffset, scrolloffset); - if(CMenuManager::m_PrefsLanguage == LANGUAGE_ITALIAN) + if(FrontEndMenuManager.m_PrefsLanguage == LANGUAGE_ITALIAN) PrintCreditSpace(1.0, lineoffset); PrintCreditText(1.0, 1.0, TheText.Get("CRED115"), lineoffset, scrolloffset); - if(CMenuManager::m_PrefsLanguage == LANGUAGE_ITALIAN) + if(FrontEndMenuManager.m_PrefsLanguage == LANGUAGE_ITALIAN) PrintCreditSpace(1.0, lineoffset); PrintCreditText(1.0, 1.0, TheText.Get("CRED116"), lineoffset, scrolloffset); - if(CMenuManager::m_PrefsLanguage == LANGUAGE_ITALIAN) + if(FrontEndMenuManager.m_PrefsLanguage == LANGUAGE_ITALIAN) PrintCreditSpace(1.0, lineoffset); PrintCreditText(1.0, 1.0, TheText.Get("CRED117"), lineoffset, scrolloffset); - if(CMenuManager::m_PrefsLanguage == LANGUAGE_ITALIAN) + if(FrontEndMenuManager.m_PrefsLanguage == LANGUAGE_ITALIAN) PrintCreditSpace(1.0, lineoffset); PrintCreditText(1.0, 1.0, TheText.Get("CRED118"), lineoffset, scrolloffset); - if(CMenuManager::m_PrefsLanguage == LANGUAGE_ITALIAN) + if(FrontEndMenuManager.m_PrefsLanguage == LANGUAGE_ITALIAN) PrintCreditSpace(1.0, lineoffset); PrintCreditText(1.0, 1.0, TheText.Get("CRED119"), lineoffset, scrolloffset); - if(CMenuManager::m_PrefsLanguage == LANGUAGE_ITALIAN) + if(FrontEndMenuManager.m_PrefsLanguage == LANGUAGE_ITALIAN) PrintCreditSpace(1.0, lineoffset); PrintCreditText(1.0, 1.0, TheText.Get("CRED120"), lineoffset, scrolloffset); - if(CMenuManager::m_PrefsLanguage == LANGUAGE_ITALIAN) + if(FrontEndMenuManager.m_PrefsLanguage == LANGUAGE_ITALIAN) PrintCreditSpace(1.0, lineoffset); PrintCreditText(1.0, 1.0, TheText.Get("CRED121"), lineoffset, scrolloffset); - if(CMenuManager::m_PrefsLanguage == LANGUAGE_ITALIAN) + if(FrontEndMenuManager.m_PrefsLanguage == LANGUAGE_ITALIAN) PrintCreditSpace(1.0, lineoffset); PrintCreditText(1.0, 1.0, TheText.Get("CRED122"), lineoffset, scrolloffset); - if(CMenuManager::m_PrefsLanguage == LANGUAGE_ITALIAN) + if(FrontEndMenuManager.m_PrefsLanguage == LANGUAGE_ITALIAN) PrintCreditSpace(1.0, lineoffset); PrintCreditText(1.0, 1.0, TheText.Get("CRED123"), lineoffset, scrolloffset); - if(CMenuManager::m_PrefsLanguage == LANGUAGE_ITALIAN) + if(FrontEndMenuManager.m_PrefsLanguage == LANGUAGE_ITALIAN) PrintCreditSpace(1.0, lineoffset); PrintCreditText(1.0, 1.0, TheText.Get("CRED124"), lineoffset, scrolloffset); - if(CMenuManager::m_PrefsLanguage == LANGUAGE_ITALIAN) + if(FrontEndMenuManager.m_PrefsLanguage == LANGUAGE_ITALIAN) PrintCreditSpace(1.0, lineoffset); PrintCreditText(1.0, 1.0, TheText.Get("CRED125"), lineoffset, scrolloffset); - if(CMenuManager::m_PrefsLanguage == LANGUAGE_ITALIAN) + if(FrontEndMenuManager.m_PrefsLanguage == LANGUAGE_ITALIAN) PrintCreditSpace(1.0, lineoffset); PrintCreditText(1.0, 1.0, TheText.Get("CRED126"), lineoffset, scrolloffset); - if(CMenuManager::m_PrefsLanguage == LANGUAGE_ITALIAN) + if(FrontEndMenuManager.m_PrefsLanguage == LANGUAGE_ITALIAN) PrintCreditSpace(1.0, lineoffset); PrintCreditText(1.0, 1.0, TheText.Get("CRED127"), lineoffset, scrolloffset); - if(CMenuManager::m_PrefsLanguage == LANGUAGE_ITALIAN) + if(FrontEndMenuManager.m_PrefsLanguage == LANGUAGE_ITALIAN) PrintCreditSpace(1.0, lineoffset); PrintCreditText(1.0, 1.0, TheText.Get("CRED128"), lineoffset, scrolloffset); - if(CMenuManager::m_PrefsLanguage == LANGUAGE_ITALIAN) + if(FrontEndMenuManager.m_PrefsLanguage == LANGUAGE_ITALIAN) PrintCreditSpace(1.0, lineoffset); PrintCreditText(1.0, 1.0, TheText.Get("CRED129"), lineoffset, scrolloffset); - if(CMenuManager::m_PrefsLanguage == LANGUAGE_ITALIAN) + if(FrontEndMenuManager.m_PrefsLanguage == LANGUAGE_ITALIAN) PrintCreditSpace(1.0, lineoffset); PrintCreditText(1.0, 1.0, TheText.Get("CRED130"), lineoffset, scrolloffset); - if(CMenuManager::m_PrefsLanguage == LANGUAGE_ITALIAN) + if(FrontEndMenuManager.m_PrefsLanguage == LANGUAGE_ITALIAN) PrintCreditSpace(1.0, lineoffset); PrintCreditText(1.0, 1.0, TheText.Get("CRED131"), lineoffset, scrolloffset); - if(CMenuManager::m_PrefsLanguage == LANGUAGE_ITALIAN) + if(FrontEndMenuManager.m_PrefsLanguage == LANGUAGE_ITALIAN) PrintCreditSpace(1.0, lineoffset); PrintCreditText(1.0, 1.0, TheText.Get("CRED132"), lineoffset, scrolloffset); - if(CMenuManager::m_PrefsLanguage == LANGUAGE_ITALIAN) + if(FrontEndMenuManager.m_PrefsLanguage == LANGUAGE_ITALIAN) PrintCreditSpace(1.0, lineoffset); PrintCreditText(1.0, 1.0, TheText.Get("CRED133"), lineoffset, scrolloffset); - if(CMenuManager::m_PrefsLanguage == LANGUAGE_ITALIAN) + if(FrontEndMenuManager.m_PrefsLanguage == LANGUAGE_ITALIAN) PrintCreditSpace(1.0, lineoffset); PrintCreditText(1.0, 1.0, TheText.Get("CRED134"), lineoffset, scrolloffset); PrintCreditSpace(2.0f, lineoffset); diff --git a/src/render/Draw.cpp b/src/render/Draw.cpp index b31cc624..e2dfc8d9 100644 --- a/src/render/Draw.cpp +++ b/src/render/Draw.cpp @@ -19,24 +19,23 @@ uint8 CDraw::FadeGreen; uint8 CDraw::FadeBlue; float -CDraw::FindAspectRatio(void) +CDraw::CalculateAspectRatio(void) { -#ifndef ASPECT_RATIO_SCALE - if(FrontEndMenuManager.m_PrefsUseWideScreen) - return 16.0f/9.0f; - else - return 4.0f/3.0f; + if (FrontEndMenuManager.m_PrefsUseWideScreen) { + if (TheCamera.m_WideScreenOn) + CDraw::ms_fAspectRatio = 5.f / 3.f; // It's used on theatrical showings according to Wiki + else +#ifdef ASPECT_RATIO_SCALE + CDraw::ms_fAspectRatio = FrontEndMenuManager.m_PrefsUseWideScreen == AR_AUTO ? SCREEN_WIDTH / SCREEN_HEIGHT : 16.f / 9.f; #else - switch (FrontEndMenuManager.m_PrefsUseWideScreen) { - case AR_AUTO: - return SCREEN_WIDTH / SCREEN_HEIGHT; - default: - case AR_4_3: - return 4.0f / 3.0f; - case AR_16_9: - return 16.0f / 9.0f; - }; + CDraw::ms_fAspectRatio = 16.f / 9.f; #endif + } else if (TheCamera.m_WideScreenOn) { + CDraw::ms_fAspectRatio = 5.f/4.f; + } else { + CDraw::ms_fAspectRatio = 4.f/3.f; + } + return CDraw::ms_fAspectRatio; } #ifdef ASPECT_RATIO_SCALE diff --git a/src/render/Draw.h b/src/render/Draw.h index 55958a2a..46e85e49 100644 --- a/src/render/Draw.h +++ b/src/render/Draw.h @@ -38,12 +38,10 @@ public: static void SetFOV(float fov); static float GetFOV(void) { return ms_fFOV; } - static float FindAspectRatio(void); + static float CalculateAspectRatio(void); #ifdef ASPECT_RATIO_SCALE static float ConvertFOV(float fov); +#endif static float GetAspectRatio(void) { return ms_fAspectRatio; } static void SetAspectRatio(float ratio) { ms_fAspectRatio = ratio; } -#else - static float GetAspectRatio(void) { return FindAspectRatio(); } -#endif }; diff --git a/src/render/Fluff.cpp b/src/render/Fluff.cpp index 59ac1652..1056d6ff 100644 --- a/src/render/Fluff.cpp +++ b/src/render/Fluff.cpp @@ -382,7 +382,7 @@ void CScrollBar::Update() m_pMessage = FindTimeMessage(); break; case 6: - if (CMenuManager::m_PrefsLanguage == LANGUAGE_FRENCH || CMenuManager::m_PrefsLanguage == LANGUAGE_GERMAN) + if (FrontEndMenuManager.m_PrefsLanguage == LANGUAGE_FRENCH || FrontEndMenuManager.m_PrefsLanguage == LANGUAGE_GERMAN) m_pMessage = FindTimeMessage(); else m_pMessage = "WWW.GRANDTHEFTAUTO3.COM "; @@ -602,7 +602,7 @@ void CScrollBar::Update() m_pMessage = "FREE FLUFFY DICE WITH ALL PURCHASES. . ."; break; case 9: - if (CMenuManager::m_PrefsLanguage == LANGUAGE_FRENCH || CMenuManager::m_PrefsLanguage == LANGUAGE_GERMAN) + if (FrontEndMenuManager.m_PrefsLanguage == LANGUAGE_FRENCH || FrontEndMenuManager.m_PrefsLanguage == LANGUAGE_GERMAN) m_pMessage = "QUICK, TAKE A LOOK AT OUR CURRENT STOCK )CAUSE THESE AUTOS ARE MOVIN) FAST . . . "; else m_pMessage = "HTTP:((ROCKSTARGAMES.COM(GRANDTHEFTAUTO3(CAPITALAUTOS "; diff --git a/src/render/Font.h b/src/render/Font.h index 9b4e7132..48f5703d 100644 --- a/src/render/Font.h +++ b/src/render/Font.h @@ -68,8 +68,8 @@ class CFont static int16 Size[MAX_FONTS][193]; #endif static int16 NewLine; - static CSprite2d Sprite[MAX_FONTS]; public: + static CSprite2d Sprite[MAX_FONTS]; static CFontDetails Details; static void Initialise(void); diff --git a/src/render/Glass.cpp b/src/render/Glass.cpp index 6f17013c..ac892ddb 100644 --- a/src/render/Glass.cpp +++ b/src/render/Glass.cpp @@ -13,6 +13,7 @@ #include "Shadows.h" #include "ModelIndices.h" #include "main.h" +#include "soundlist.h" uint32 CGlass::NumGlassEntities; @@ -101,7 +102,7 @@ CFallingGlassPane::Update(void) pos = CVector(GetPosition().x, GetPosition().y, m_fGroundZ); - PlayOneShotScriptObject(_SCRSOUND_GLASS_SHARD, pos); + PlayOneShotScriptObject(SCRIPT_SOUND_GLASS_LIGHT_BREAK, pos); RwRGBA color = { 255, 255, 255, 255 }; @@ -627,7 +628,7 @@ CGlass::WindowRespondsToCollision(CEntity *entity, float amount, CVector speed, if ( amount > 300.0f ) { - PlayOneShotScriptObject(_SCRSOUND_GLASS_SMASH_1, object->GetPosition()); + PlayOneShotScriptObject(SCRIPT_SOUND_GLASS_BREAK_L, object->GetPosition()); GeneratePanesForWindow(0, CVector(minx, miny, minz), @@ -637,7 +638,7 @@ CGlass::WindowRespondsToCollision(CEntity *entity, float amount, CVector speed, } else { - PlayOneShotScriptObject(_SCRSOUND_GLASS_SMASH_2, object->GetPosition()); + PlayOneShotScriptObject(SCRIPT_SOUND_GLASS_BREAK_S, object->GetPosition()); GeneratePanesForWindow(1, CVector(minx, miny, minz), @@ -659,7 +660,7 @@ CGlass::WindowRespondsToSoftCollision(CEntity *entity, float amount) if ( amount > 50.0f && !object->bGlassCracked ) { - PlayOneShotScriptObject(_SCRSOUND_GLASS_CRACK, object->GetPosition()); + PlayOneShotScriptObject(SCRIPT_SOUND_GLASS_CRACK, object->GetPosition()); object->bGlassCracked = true; } } @@ -675,7 +676,7 @@ CGlass::WasGlassHitByBullet(CEntity *entity, CVector point) { if ( !object->bGlassCracked ) { - PlayOneShotScriptObject(_SCRSOUND_GLASS_CRACK, object->GetPosition()); + PlayOneShotScriptObject(SCRIPT_SOUND_GLASS_CRACK, object->GetPosition()); object->bGlassCracked = true; } else diff --git a/src/render/Hud.cpp b/src/render/Hud.cpp index e06cc143..5d1542ef 100644 --- a/src/render/Hud.cpp +++ b/src/render/Hud.cpp @@ -21,6 +21,28 @@ #include "User.h" #include "World.h" +// Game has colors inlined in code. +// For easier modification we collect them here: +CRGBA MONEY_COLOR(0, 207, 133, 255); +CRGBA AMMO_COLOR(255, 150, 225, 255); +CRGBA HEALTH_COLOR(255, 150, 225, 255); +CRGBA ARMOUR_COLOR(185, 185, 185, 255); +CRGBA NOTWANTED_COLOR(27, 89, 130, 255); +CRGBA WANTED_COLOR_FLASH(62, 141, 181, 255); +CRGBA WANTED_COLOR(97, 194, 247, 255); +CRGBA ZONE_COLOR(45, 155, 90, 255); +CRGBA VEHICLE_COLOR(97, 194, 247, 255); +CRGBA CLOCK_COLOR(97, 194, 247, 255); +CRGBA TIMER_COLOR(97, 194, 247, 255); +CRGBA COUNTER_COLOR(97, 194, 247, 255); +CRGBA PAGER_COLOR(32, 162, 66, 205); +CRGBA RADARDISC_COLOR(255, 255, 255, 255); +CRGBA BIGMESSAGE_COLOR(85, 119, 133, 255); +CRGBA WASTEDBUSTED_COLOR(255, 150, 225, 255); +CRGBA ODDJOB_COLOR(89, 115, 150, 255); +CRGBA ODDJOB2_COLOR(156, 91, 40, 255); +CRGBA MISSIONTITLE_COLOR(220, 172, 2, 255); + wchar CHud::m_HelpMessage[256]; wchar CHud::m_LastHelpMessage[256]; uint32 CHud::m_HelpMessageState; @@ -66,6 +88,22 @@ float CHud::PagerXOffset; int16 CHud::PagerTimer; int16 CHud::PagerOn; +uint32 CHud::m_WantedFadeTimer; +uint32 CHud::m_WantedState; +uint32 CHud::m_WantedTimer; +uint32 CHud::m_EnergyLostFadeTimer; +uint32 CHud::m_EnergyLostState; +uint32 CHud::m_EnergyLostTimer; +uint32 CHud::m_DisplayScoreFadeTimer; +uint32 CHud::m_DisplayScoreState; +uint32 CHud::m_DisplayScoreTimer; +uint32 CHud::m_WeaponFadeTimer; +uint32 CHud::m_WeaponState; +uint32 CHud::m_WeaponTimer; + +uint32 CHud::m_LastDisplayScore; +uint32 CHud::m_LastWanted; + CSprite2d CHud::Sprites[NUM_HUD_SPRITES]; struct @@ -103,6 +141,10 @@ RwTexture *gpRocketSightTex; void CHud::Draw() { + RwRenderStateSet(rwRENDERSTATETEXTUREFILTER, (void*)rwFILTERNEAREST); + RwRenderStateSet(rwRENDERSTATETEXTUREADDRESS, (void*)rwTEXTUREADDRESSCLAMP); + RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)FALSE); + // disable hud via second controller if (CPad::GetPad(1)->GetStartJustDown()) m_Wants_To_Draw_Hud = !m_Wants_To_Draw_Hud; @@ -114,22 +156,28 @@ void CHud::Draw() bool DrawCrossHair = 0; bool DrawCrossHairPC = 0; - int32 WeaponType = FindPlayerPed()->m_weapons[FindPlayerPed()->m_currentWeapon].m_eWeaponType; + CPlayerPed *playerPed = FindPlayerPed(); + eWeaponType WeaponType = playerPed->GetWeapon()->m_eWeaponType; int32 Mode = TheCamera.Cams[TheCamera.ActiveCam].Mode; - if (Mode == CCam::MODE_SNIPER || Mode == CCam::MODE_ROCKETLAUNCHER || Mode == CCam::MODE_M16_1STPERSON || Mode == CCam::MODE_HELICANNON_1STPERSON) - DrawCrossHair = 1; - if (Mode == CCam::MODE_M16_1STPERSON_RUNABOUT || Mode == CCam::MODE_ROCKETLAUNCHER_RUNABOUT || Mode == CCam::MODE_SNIPER_RUNABOUT) - DrawCrossHairPC = 1; + // TODO(Miami): New cam mode + if ((Mode == CCam::MODE_SNIPER || Mode == CCam::MODE_ROCKETLAUNCHER || Mode == CCam::MODE_M16_1STPERSON || Mode == CCam::MODE_HELICANNON_1STPERSON/* || Mode == 46*/) + && playerPed && !playerPed->GetWeapon()->IsTypeMelee()) + DrawCrossHair = true; - /* - Draw Crosshairs - */ - if (TheCamera.Cams[TheCamera.ActiveCam].Using3rdPersonMouseCam() && - (!CPad::GetPad(0)->GetLookBehindForPed() || TheCamera.m_bPlayerIsInGarage) || Mode == CCam::MODE_1STPERSON_RUNABOUT) { - if (FindPlayerPed() && !FindPlayerPed()->EnteringCar()) { - if ((WeaponType >= WEAPONTYPE_COLT45 && WeaponType <= WEAPONTYPE_M16) || WeaponType == WEAPONTYPE_FLAMETHROWER) - DrawCrossHairPC = 1; + if (Mode == CCam::MODE_M16_1STPERSON_RUNABOUT || Mode == CCam::MODE_ROCKETLAUNCHER_RUNABOUT || Mode == CCam::MODE_SNIPER_RUNABOUT) + DrawCrossHairPC = true; + if (TheCamera.Cams[TheCamera.ActiveCam].Using3rdPersonMouseCam() && (!CPad::GetPad(0)->GetLookBehindForPed() || TheCamera.m_bPlayerIsInGarage) + || Mode == CCam::MODE_1STPERSON_RUNABOUT) { + if (playerPed) { + if (playerPed->m_nPedState != PED_ENTER_CAR && playerPed->m_nPedState != PED_CARJACK) { + + if (WeaponType >= WEAPONTYPE_COLT45 && WeaponType <= WEAPONTYPE_RUGER + || WeaponType == WEAPONTYPE_M60 || WeaponType == WEAPONTYPE_MINIGUN + || WeaponType == WEAPONTYPE_FLAMETHROWER) { + DrawCrossHairPC = 1; + } + } } } @@ -149,7 +197,7 @@ void CHud::Draw() #ifdef ASPECT_RATIO_SCALE f3rdY -= SCREEN_SCALE_Y(2.0f); #endif - if (FindPlayerPed() && WeaponType == WEAPONTYPE_M16) { + if (playerPed && (WeaponType == WEAPONTYPE_M4 || WeaponType == WEAPONTYPE_RUGER || WeaponType == WEAPONTYPE_M60)) { rect.left = f3rdX - SCREEN_SCALE_X(32.0f * 0.6f); rect.top = f3rdY - SCREEN_SCALE_Y(32.0f * 0.6f); rect.right = f3rdX + SCREEN_SCALE_X(32.0f * 0.6f); @@ -165,8 +213,7 @@ void CHud::Draw() Sprites[HUD_SITEM16].Draw(CRect(rect), CRGBA(255, 255, 255, 255)); } - } - else { + } else { if (Mode == CCam::MODE_M16_1STPERSON || Mode == CCam::MODE_M16_1STPERSON_RUNABOUT || Mode == CCam::MODE_HELICANNON_1STPERSON) { @@ -193,8 +240,11 @@ void CHud::Draw() RwRenderStateSet(rwRENDERSTATETEXTURERASTER, RwTextureGetRaster(gpRocketSightTex)); CSprite::RenderOneXLUSprite(SCREEN_WIDTH / 2, SCREEN_HEIGHT / 2, 1.0f, SCREEN_SCALE_X(40.0f), SCREEN_SCALE_Y(40.0f), (100.0f * fMultBright), (200.0f * fMultBright), (100.0f * fMultBright), 255, 1.0f, 255); + RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)FALSE); } else { + + // TODO(Miami) // Sniper rect.left = (SCREEN_WIDTH / 2) - SCREEN_SCALE_X(210.0f); rect.top = (SCREEN_HEIGHT / 2) - SCREEN_SCALE_Y(210.0f); @@ -221,9 +271,9 @@ void CHud::Draw() Sprites[HUD_SITESNIPER].Draw(CRect(rect), CRGBA(255, 255, 255, 255)); } } - RwRenderStateSet(rwRENDERSTATETEXTUREFILTER, (void *)rwFILTERLINEAR); RwRenderStateSet(rwRENDERSTATESRCBLEND, (void *)rwBLENDSRCALPHA); RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void *)rwBLENDINVSRCALPHA); + RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)TRUE); } else { SpriteBrightness = 0; @@ -232,34 +282,46 @@ void CHud::Draw() /* DrawMoneyCounter */ + wchar sPrint[16]; wchar sPrintIcon[16]; char sTemp[16]; + float alpha; - sprintf(sTemp, "$%08d", CWorld::Players[CWorld::PlayerInFocus].m_nVisibleMoney); - AsciiToUnicode(sTemp, sPrint); + if (m_LastDisplayScore == CWorld::Players[CWorld::PlayerInFocus].m_nVisibleMoney) { + alpha = CHud::DrawFadeState(HUD_SCORE_FADING, 0); + } else { + alpha = CHud::DrawFadeState(HUD_SCORE_FADING, 1); + m_LastDisplayScore = CWorld::Players[CWorld::PlayerInFocus].m_nVisibleMoney; + } + if (m_DisplayScoreState != FADED_OUT) { + sprintf(sTemp, "$%08d", CWorld::Players[CWorld::PlayerInFocus].m_nVisibleMoney); + AsciiToUnicode(sTemp, sPrint); - CFont::SetPropOff(); - CFont::SetBackgroundOff(); - CFont::SetScale(SCREEN_SCALE_X(0.8f), SCREEN_SCALE_Y(1.35f)); - CFont::SetCentreOff(); - CFont::SetRightJustifyOn(); - CFont::SetRightJustifyWrap(0.0f); - CFont::SetBackGroundOnlyTextOff(); - CFont::SetFontStyle(FONT_HEADING); - CFont::SetPropOff(); - CFont::SetColor(CRGBA(0, 0, 0, 255)); + CFont::SetPropOff(); + CFont::SetBackgroundOff(); + CFont::SetScale(SCREEN_SCALE_X(HUD_TEXT_SCALE_X), SCREEN_SCALE_Y(HUD_TEXT_SCALE_Y)); + CFont::SetCentreOff(); + CFont::SetRightJustifyOn(); + CFont::SetRightJustifyWrap(0.0f); + CFont::SetBackGroundOnlyTextOff(); + CFont::SetFontStyle(FONT_HEADING); + CFont::SetPropOff(); + CFont::SetDropShadowPosition(2); + CFont::SetDropColor(CRGBA(0, 0, 0, alpha)); + MONEY_COLOR.a = alpha; + CFont::SetColor(MONEY_COLOR); - CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(110.0f - 2.0f), SCREEN_SCALE_Y(43.0f + 2.0f), sPrint); - - CFont::SetColor(CRGBA(89, 115, 150, 255)); - CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(110.0f), SCREEN_SCALE_Y(43.0f), sPrint); + if (FrontEndMenuManager.m_PrefsShowHud) { + CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(110.0f), SCREEN_SCALE_Y(43.0f), sPrint); + } + } /* DrawAmmo */ CWeaponInfo *weaponInfo = CWeaponInfo::GetWeaponInfo((eWeaponType)WeaponType); - CWeapon *weapon = FindPlayerPed()->GetWeapon(); + CWeapon *weapon = playerPed->GetWeapon(); uint32 AmmoAmount = weaponInfo->m_nAmountofAmmunition; uint32 AmmoInClip = weapon->m_nAmmoInClip; uint32 TotalAmmo = weapon->m_nAmmoTotal; @@ -325,17 +387,18 @@ void CHud::Draw() } CFont::SetBackgroundOff(); - CFont::SetScale(SCREEN_SCALE_X(0.4f), SCREEN_SCALE_Y(0.6f)); + CFont::SetScale(SCREEN_SCALE_X(0.5f), SCREEN_SCALE_Y(0.8f)); CFont::SetJustifyOff(); CFont::SetCentreOn(); CFont::SetCentreSize(SCREEN_SCALE_X(640.0f)); CFont::SetPropOn(); + CFont::SetDropShadowPosition(0); CFont::SetFontStyle(FONT_BANK); - if (!CDarkel::FrenzyOnGoing() && weaponInfo->m_nWeaponSlot > 1 && weapon->m_eWeaponType != WEAPONTYPE_DETONATOR) { + if (Min(9999, TotalAmmo - AmmoInClip) != 9999 && !CDarkel::FrenzyOnGoing() && weaponInfo->m_nWeaponSlot > 1 && weapon->m_eWeaponType != WEAPONTYPE_DETONATOR) { CFont::SetDropShadowPosition(2); CFont::SetDropColor(CRGBA(0, 0, 0, 255)); - CFont::SetColor(CRGBA(255, 150, 225, 255)); + CFont::SetColor(AMMO_COLOR); CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(66.0f), SCREEN_SCALE_Y(90.0f), sPrint); CFont::SetDropShadowPosition(0); } @@ -344,7 +407,7 @@ void CHud::Draw() DrawHealth */ CFont::SetBackgroundOff(); - CFont::SetScale(SCREEN_SCALE_X(0.8f), SCREEN_SCALE_Y(1.35f)); + CFont::SetScale(SCREEN_SCALE_X(HUD_TEXT_SCALE_X), SCREEN_SCALE_Y(HUD_TEXT_SCALE_Y)); CFont::SetJustifyOff(); CFont::SetCentreOff(); CFont::SetRightJustifyWrap(0.0f); @@ -354,16 +417,16 @@ void CHud::Draw() if (m_ItemToFlash == ITEM_HEALTH && CTimer::GetFrameCounter() & 8 || m_ItemToFlash != ITEM_HEALTH - || FindPlayerPed()->m_fHealth < 10 + || playerPed->m_fHealth < 10 && CTimer::GetFrameCounter() & 8) { - if (FindPlayerPed()->m_fHealth >= 10 - || FindPlayerPed()->m_fHealth < 10 && CTimer::GetFrameCounter() & 8) { + if (playerPed->m_fHealth >= 10 + || playerPed->m_fHealth < 10 && CTimer::GetFrameCounter() & 8) { AsciiToUnicode("{", sPrintIcon); #ifdef FIX_BUGS - sprintf(sTemp, "%03d", int32(FindPlayerPed()->m_fHealth + 0.5f)); + sprintf(sTemp, "%03d", int32(playerPed->m_fHealth + 0.5f)); #else - sprintf(sTemp, "%03d", (int32)FindPlayerPed()->m_fHealth); + sprintf(sTemp, "%03d", (int32)playerPed->m_fHealth); #endif AsciiToUnicode(sTemp, sPrint); @@ -373,7 +436,7 @@ void CHud::Draw() if (!CWorld::Players[CWorld::PlayerInFocus].m_nTimeLastHealthLoss || CTimer::GetTimeInMilliseconds() > CWorld::Players[CWorld::PlayerInFocus].m_nTimeLastHealthLoss + 2000 || CTimer::GetFrameCounter() & 4) { CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(164.0f - 2.0f), SCREEN_SCALE_Y(65.0f + 2.0f), sPrintIcon); } - CFont::SetColor(CRGBA(186, 101, 50, 255)); + CFont::SetColor(HEALTH_COLOR); CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(110.0f), SCREEN_SCALE_Y(65.0f), sPrint); @@ -387,13 +450,13 @@ void CHud::Draw() DrawArmour */ if (m_ItemToFlash == ITEM_ARMOUR && CTimer::GetFrameCounter() & 8 || m_ItemToFlash != ITEM_ARMOUR) { - CFont::SetScale(SCREEN_SCALE_X(0.8f), SCREEN_SCALE_Y(1.35f)); - if (FindPlayerPed()->m_fArmour > 1.0f) { + CFont::SetScale(SCREEN_SCALE_X(HUD_TEXT_SCALE_X), SCREEN_SCALE_Y(HUD_TEXT_SCALE_Y)); + if (playerPed->m_fArmour > 1.0f) { AsciiToUnicode("[", sPrintIcon); #ifdef FIX_BUGS - sprintf(sTemp, "%03d", int32(FindPlayerPed()->m_fArmour + 0.5f)); + sprintf(sTemp, "%03d", int32(playerPed->m_fArmour + 0.5f)); #else - sprintf(sTemp, "%03d", (int32)FindPlayerPed()->m_fArmour); + sprintf(sTemp, "%03d", (int32)playerPed->m_fArmour); #endif AsciiToUnicode(sTemp, sPrint); @@ -404,7 +467,7 @@ void CHud::Draw() CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(234.0f - 2.0f), SCREEN_SCALE_Y(65.0f + 2.0f), sPrintIcon); } - CFont::SetColor(CRGBA(124, 140, 95, 255)); + CFont::SetColor(ARMOUR_COLOR); CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(182.0f), SCREEN_SCALE_Y(65.0f), sPrint); @@ -417,26 +480,46 @@ void CHud::Draw() /* DrawWantedLevel */ - CFont::SetBackgroundOff(); - CFont::SetScale(SCREEN_SCALE_X(0.7f), SCREEN_SCALE_Y(1.25f)); - CFont::SetJustifyOff(); - CFont::SetCentreOff(); - CFont::SetRightJustifyOn(); - CFont::SetPropOn(); - CFont::SetFontStyle(FONT_HEADING); + if (m_LastWanted == playerPed->m_pWanted->m_nWantedLevel) + alpha = CHud::DrawFadeState(HUD_WANTED_FADING, 0); + else { + alpha = CHud::DrawFadeState(HUD_WANTED_FADING, 1); + m_LastWanted = playerPed->m_pWanted->m_nWantedLevel; + } - AsciiToUnicode("]", sPrintIcon); + if (m_WantedState != FADED_OUT) { + CFont::SetBackgroundOff(); + CFont::SetScale(SCREEN_SCALE_X(HUD_TEXT_SCALE_X), SCREEN_SCALE_Y(HUD_TEXT_SCALE_Y)); + CFont::SetJustifyOff(); + CFont::SetCentreOff(); + CFont::SetRightJustifyOn(); + CFont::SetPropOn(); + CFont::SetFontStyle(FONT_HEADING); + CFont::SetDropShadowPosition(2); // TODO(Miami): Remove that, VC keeps that open above + CFont::SetDropColor(CRGBA(0,0,0,alpha)); // TODO(Miami): Remove that, VC keeps that open above - for (int i = 0; i < 6; i++) { - CFont::SetColor(CRGBA(0, 0, 0, 255)); - CFont::PrintString(2.0f + SCREEN_SCALE_FROM_RIGHT(110.0f - 2.0f + 23.0f * i), SCREEN_SCALE_Y(87.0f + 2.0f), sPrintIcon); - if (FindPlayerPed()->m_pWanted->m_nWantedLevel > i - && (CTimer::GetTimeInMilliseconds() > FindPlayerPed()->m_pWanted->m_nLastWantedLevelChange - + 2000 || CTimer::GetFrameCounter() & 4)) { + AsciiToUnicode("]", sPrintIcon); - CFont::SetColor(CRGBA(193, 164, 120, 255)); - CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(110.0f + 23.0f * i), SCREEN_SCALE_Y(87.0f), sPrintIcon); + for (int i = 0; i < 6; i++) { + if (FrontEndMenuManager.m_PrefsShowHud) { + if (playerPed->m_pWanted->m_nWantedLevel > i + && (CTimer::GetTimeInMilliseconds() > playerPed->m_pWanted->m_nLastWantedLevelChange + + 2000 || CTimer::GetFrameCounter() & 4)) { + + WANTED_COLOR.a = alpha; + CFont::SetColor(WANTED_COLOR); + CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(110.0f + 23.0f * i), SCREEN_SCALE_Y(87.0f), sPrintIcon); + + // TODO(Miami): There is one more condition in here + } else if (playerPed->m_pWanted->m_nWantedLevel <= i) { + NOTWANTED_COLOR.a = alpha; + CFont::SetColor(NOTWANTED_COLOR); + CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(110.0f + 23.0f * i), SCREEN_SCALE_Y(87.0f), sPrintIcon); + } + } } + + CFont::SetDropShadowPosition(0); // TODO(Miami): Remove that, VC keeps that open } /* @@ -521,15 +604,20 @@ void CHud::Draw() else CFont::SetScale(SCREEN_SCALE_X(1.2f), SCREEN_SCALE_Y(1.2f)); + CFont::SetSlantRefPoint(SCREEN_SCALE_FROM_RIGHT(32.0f), SCREEN_SCALE_FROM_BOTTOM(128.0f)); + CFont::SetSlant(0.15f); + CFont::SetRightJustifyOn(); CFont::SetRightJustifyWrap(0.0f); CFont::SetBackGroundOnlyTextOff(); CFont::SetFontStyle(FONT_BANK); CFont::SetColor(CRGBA(0, 0, 0, fZoneAlpha)); - CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(32.0f) + SCREEN_SCALE_X(1.0f), SCREEN_SCALE_FROM_BOTTOM(30.0f) + SCREEN_SCALE_Y(1.0f), m_ZoneToPrint); + CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(32.0f) + SCREEN_SCALE_X(1.0f), SCREEN_SCALE_FROM_BOTTOM(128.0f) + SCREEN_SCALE_Y(1.0f), m_ZoneToPrint); - CFont::SetColor(CRGBA(152, 154, 82, fZoneAlpha)); - CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(32.0f), SCREEN_SCALE_FROM_BOTTOM(30.0f), m_ZoneToPrint); + CFont::SetColor(CRGBA(ZONE_COLOR.r, ZONE_COLOR.g, ZONE_COLOR.b, fZoneAlpha)); + CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(32.0f), SCREEN_SCALE_FROM_BOTTOM(128.0f), m_ZoneToPrint); + + CFont::SetSlant(0.f); } } } @@ -615,15 +703,20 @@ void CHud::Draw() else CFont::SetScale(SCREEN_SCALE_X(1.2f * 0.85f), SCREEN_SCALE_Y(1.2f)); + CFont::SetSlantRefPoint(SCREEN_SCALE_FROM_RIGHT(32.0f), SCREEN_SCALE_FROM_BOTTOM(105.0f)); + CFont::SetSlant(0.15f); + CFont::SetRightJustifyOn(); CFont::SetRightJustifyWrap(0.0f); CFont::SetBackGroundOnlyTextOff(); CFont::SetFontStyle(FONT_BANK); CFont::SetColor(CRGBA(0, 0, 0, fVehicleAlpha)); - CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(32.0f) + SCREEN_SCALE_X(1.0f), SCREEN_SCALE_FROM_BOTTOM(55.0f) + SCREEN_SCALE_Y(1.0f), m_pVehicleNameToPrint); + CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(32.0f) + SCREEN_SCALE_X(1.0f), SCREEN_SCALE_FROM_BOTTOM(105.f) + SCREEN_SCALE_Y(1.0f), m_pVehicleNameToPrint); - CFont::SetColor(CRGBA(194, 165, 120, fVehicleAlpha)); - CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(32.0f), SCREEN_SCALE_FROM_BOTTOM(55.0f), m_pVehicleNameToPrint); + CFont::SetColor(CRGBA(VEHICLE_COLOR.r, VEHICLE_COLOR.g, VEHICLE_COLOR.b, fVehicleAlpha)); + CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(32.0f), SCREEN_SCALE_FROM_BOTTOM(105.0f), m_pVehicleNameToPrint); + + CFont::SetSlant(0.f); } } } @@ -640,7 +733,7 @@ void CHud::Draw() CFont::SetJustifyOff(); CFont::SetCentreOff(); CFont::SetBackgroundOff(); - CFont::SetScale(SCREEN_SCALE_X(0.8f), SCREEN_SCALE_Y(1.35f)); + CFont::SetScale(SCREEN_SCALE_X(HUD_TEXT_SCALE_X), SCREEN_SCALE_Y(HUD_TEXT_SCALE_Y)); CFont::SetBackGroundOnlyTextOff(); CFont::SetPropOff(); CFont::SetFontStyle(FONT_HEADING); @@ -654,7 +747,7 @@ void CHud::Draw() CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(111.0f) + SCREEN_SCALE_X(2.0f), SCREEN_SCALE_Y(22.0f) + SCREEN_SCALE_Y(2.0f), sPrint); - CFont::SetColor(CRGBA(194, 165, 120, 255)); + CFont::SetColor(CLOCK_COLOR); CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(111.0f), SCREEN_SCALE_Y(22.0f), sPrint); /* @@ -689,7 +782,7 @@ void CHud::Draw() AsciiToUnicode(CUserDisplay::OnscnTimer.m_sEntries[0].m_bTimerBuffer, sTimer); CFont::SetPropOn(); CFont::SetBackgroundOff(); - CFont::SetScale(SCREEN_SCALE_X(0.8f), SCREEN_SCALE_Y(1.35f)); + CFont::SetScale(SCREEN_SCALE_X(HUD_TEXT_SCALE_X), SCREEN_SCALE_Y(HUD_TEXT_SCALE_Y)); CFont::SetRightJustifyOn(); CFont::SetRightJustifyWrap(0.0f); CFont::SetFontStyle(FONT_LOCALE(FONT_HEADING)); @@ -697,8 +790,8 @@ void CHud::Draw() CFont::SetBackGroundOnlyTextOn(); CFont::SetColor(CRGBA(0, 0, 0, 255)); CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(TIMER_RIGHT_OFFSET) + SCREEN_SCALE_X(2.0f), SCREEN_SCALE_Y(110.0f) + SCREEN_SCALE_Y(2.0f), sTimer); - CFont::SetScale(SCREEN_SCALE_X(0.8f), SCREEN_SCALE_Y(1.35f)); - CFont::SetColor(CRGBA(186, 101, 50, 255)); + CFont::SetScale(SCREEN_SCALE_X(HUD_TEXT_SCALE_X), SCREEN_SCALE_Y(HUD_TEXT_SCALE_Y)); + CFont::SetColor(TIMER_COLOR); CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(TIMER_RIGHT_OFFSET), SCREEN_SCALE_Y(110.0f), sTimer); if (CUserDisplay::OnscnTimer.m_sEntries[0].m_aTimerText[0]) { @@ -707,7 +800,7 @@ void CHud::Draw() CFont::SetScale(SCREEN_SCALE_X(0.64f), SCREEN_SCALE_Y(1.35f)); CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(TIMER_RIGHT_OFFSET) - SCREEN_SCALE_X(80.0f) + SCREEN_SCALE_X(2.0f), SCREEN_SCALE_Y(110.0f) + SCREEN_SCALE_Y(2.0f), TheText.Get(CUserDisplay::OnscnTimer.m_sEntries[0].m_aTimerText)); - CFont::SetColor(CRGBA(186, 101, 50, 255)); + CFont::SetColor(TIMER_COLOR); CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(TIMER_RIGHT_OFFSET) - SCREEN_SCALE_X(80.0f), SCREEN_SCALE_Y(110.0f), TheText.Get(CUserDisplay::OnscnTimer.m_sEntries[0].m_aTimerText)); } } @@ -729,7 +822,7 @@ void CHud::Draw() CFont::SetPropOn(); CFont::SetBackgroundOff(); - CFont::SetScale(SCREEN_SCALE_X(0.8f), SCREEN_SCALE_Y(1.35f)); + CFont::SetScale(SCREEN_SCALE_X(HUD_TEXT_SCALE_X), SCREEN_SCALE_Y(HUD_TEXT_SCALE_Y)); CFont::SetCentreOff(); CFont::SetRightJustifyOn(); CFont::SetRightJustifyWrap(0.0f); @@ -742,7 +835,7 @@ void CHud::Draw() CFont::SetColor(CRGBA(0, 0, 0, 255)); CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(TIMER_RIGHT_OFFSET) + SCREEN_SCALE_X(2.0f), SCREEN_SCALE_Y(132.0f) + SCREEN_SCALE_Y(2.0f), sTimer); - CFont::SetColor(CRGBA(0, 106, 164, 255)); + CFont::SetColor(COUNTER_COLOR); CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(TIMER_RIGHT_OFFSET), SCREEN_SCALE_Y(132.0f), sTimer); } else { int counter = atoi(CUserDisplay::OnscnTimer.m_sEntries[0].m_bCounterBuffer); @@ -755,11 +848,11 @@ void CHud::Draw() if (CUserDisplay::OnscnTimer.m_sEntries[0].m_aCounterText[0]) { CFont::SetPropOn(); - CFont::SetScale(SCREEN_SCALE_X(0.8f), SCREEN_SCALE_Y(1.35f)); + CFont::SetScale(SCREEN_SCALE_X(HUD_TEXT_SCALE_X), SCREEN_SCALE_Y(HUD_TEXT_SCALE_Y)); CFont::SetColor(CRGBA(0, 0, 0, 255)); CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(TIMER_RIGHT_OFFSET) - SCREEN_SCALE_X(61.0f) + SCREEN_SCALE_Y(2.0f), SCREEN_SCALE_Y(132.0f) + SCREEN_SCALE_Y(2.0f), TheText.Get(CUserDisplay::OnscnTimer.m_sEntries[0].m_aCounterText)); - CFont::SetColor(CRGBA(0, 106, 164, 255)); + CFont::SetColor(COUNTER_COLOR); CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(TIMER_RIGHT_OFFSET) - SCREEN_SCALE_X(61.0f), SCREEN_SCALE_Y(132.0f), TheText.Get(CUserDisplay::OnscnTimer.m_sEntries[0].m_aCounterText)); } } @@ -806,7 +899,7 @@ void CHud::Draw() CFont::SetBackgroundOff(); CFont::SetScale(SCREEN_SCALE_X(0.84f), SCREEN_SCALE_Y(1.0f)); - CFont::SetColor(CRGBA(32, 162, 66, 205)); + CFont::SetColor(PAGER_COLOR); CFont::SetRightJustifyOff(); CFont::SetBackgroundOff(); CFont::SetCentreOff(); @@ -827,8 +920,18 @@ void CHud::Draw() #else rect.Translate(RADAR_LEFT, SCREEN_SCALE_FROM_BOTTOM(RADAR_BOTTOM + RADAR_HEIGHT)); #endif - rect.Grow(4.0f); + + // shadow, might not be exactly accurate numbers + rect.Translate(0.f, 4.f); + rect.Grow(6.0f); + rect.top += 2.f; + rect.bottom -= 2.f; Sprites[HUD_RADARDISC].Draw(rect, CRGBA(0, 0, 0, 255)); + + rect.Translate(0.f, -4.f); + rect.top -= 2.f; + rect.bottom += 2.f; + Sprites[HUD_RADARDISC].Draw(rect, RADARDISC_COLOR); CRadar::DrawBlips(); } } @@ -983,7 +1086,7 @@ void CHud::Draw() CFont::PrintString(SCREEN_WIDTH / 2 + SCREEN_SCALE_X(2.0f), (SCREEN_HEIGHT / 2) - SCREEN_SCALE_Y(20.0f) + SCREEN_SCALE_Y(2.0f), m_BigMessage[0]); #endif - CFont::SetColor(CRGBA(85, 119, 133, BigMessageAlpha[0])); + CFont::SetColor(CRGBA(BIGMESSAGE_COLOR.r, BIGMESSAGE_COLOR.g, BIGMESSAGE_COLOR.b, BigMessageAlpha[0])); CFont::PrintString(SCREEN_WIDTH / 2, (SCREEN_HEIGHT / 2) - SCREEN_SCALE_Y(18.0f), m_BigMessage[0]); } else { @@ -1018,7 +1121,7 @@ void CHud::Draw() CFont::SetColor(CRGBA(0, 0, 0, BigMessageAlpha[2])); CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(20.0f - 4.0f), SCREEN_SCALE_FROM_BOTTOM(78.0f), m_BigMessage[2]); - CFont::SetColor(CRGBA(170, 123, 87, BigMessageAlpha[2])); + CFont::SetColor(CRGBA(WASTEDBUSTED_COLOR.r, WASTEDBUSTED_COLOR.g, WASTEDBUSTED_COLOR.b, BigMessageAlpha[2])); CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(20.0f), SCREEN_SCALE_FROM_BOTTOM(82.0f), m_BigMessage[2]); } else { @@ -1210,7 +1313,7 @@ void CHud::DrawAfterFade() CFont::SetColor(CRGBA(0, 0, 0, 255)); CFont::PrintString((SCREEN_WIDTH / 2) + SCREEN_SCALE_X(2.0f), (SCREEN_HEIGHT / 2) - SCREEN_SCALE_Y(84.0f) + SCREEN_SCALE_Y(2.0f), m_BigMessage[3]); - CFont::SetColor(CRGBA(89, 115, 150, 255)); + CFont::SetColor(ODDJOB_COLOR); CFont::PrintString((SCREEN_WIDTH / 2), (SCREEN_HEIGHT / 2) - SCREEN_SCALE_Y(84.0f), m_BigMessage[3]); } @@ -1226,7 +1329,7 @@ void CHud::DrawAfterFade() CFont::PrintString((SCREEN_WIDTH / 2) - SCREEN_SCALE_X(2.0f), (SCREEN_HEIGHT / 2) - SCREEN_SCALE_Y(84.0f) - SCREEN_SCALE_Y(2.0f), m_BigMessage[4]); - CFont::SetColor(CRGBA(89, 115, 150, 255)); + CFont::SetColor(ODDJOB_COLOR); CFont::PrintString((SCREEN_WIDTH / 2), (SCREEN_HEIGHT / 2) - SCREEN_SCALE_Y(84.0f), m_BigMessage[4]); } @@ -1284,12 +1387,12 @@ void CHud::DrawAfterFade() #ifdef BETA_SLIDING_TEXT CFont::PrintString(SCREEN_WIDTH / 2 + SCREEN_SCALE_X(2.0f) - SCREEN_SCALE_X(OddJob2XOffset), SCREEN_HEIGHT / 2 - SCREEN_SCALE_Y(20.0f) + SCREEN_SCALE_Y(2.0f), m_BigMessage[5]); - CFont::SetColor(CRGBA(156, 91, 40, 255)); + CFont::SetColor(ODDJOB2_COLOR); CFont::PrintString(SCREEN_WIDTH / 2 - SCREEN_SCALE_X(OddJob2XOffset), SCREEN_HEIGHT / 2 - SCREEN_SCALE_Y(20.0f), m_BigMessage[5]); #else CFont::PrintString(SCREEN_WIDTH / 2 + SCREEN_SCALE_X(2.0f), SCREEN_HEIGHT / 2 - SCREEN_SCALE_Y(20.0f) + SCREEN_SCALE_Y(2.0f), m_BigMessage[5]); - CFont::SetColor(CRGBA(156, 91, 40, 255)); + CFont::SetColor(ODDJOB2_COLOR); CFont::PrintString(SCREEN_WIDTH / 2, SCREEN_HEIGHT / 2 - SCREEN_SCALE_Y(20.0f), m_BigMessage[5]); #endif } @@ -1334,7 +1437,7 @@ void CHud::DrawAfterFade() CFont::SetColor(CRGBA(40, 40, 40, BigMessageAlpha[1])); CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(20.0f) + SCREEN_SCALE_X(2.0f), SCREEN_SCALE_FROM_BOTTOM(120.0f) + SCREEN_SCALE_Y(2.0f), m_BigMessage[1]); - CFont::SetColor(CRGBA(220, 172, 2, BigMessageAlpha[1])); + CFont::SetColor(CRGBA(MISSIONTITLE_COLOR.r, MISSIONTITLE_COLOR.g, MISSIONTITLE_COLOR.b, BigMessageAlpha[1])); CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(20.0f), SCREEN_SCALE_FROM_BOTTOM(120.0f), m_BigMessage[1]); } else { @@ -1384,6 +1487,30 @@ void CHud::GetRidOfAllHudMessages() } } +#ifdef RELOADABLES +void CHud::ReloadTXD() +{ + for (int i = 0; i < NUM_HUD_SPRITES; ++i) { + Sprites[i].Delete(); + } + + int HudTXD = CTxdStore::FindTxdSlot("hud"); + CTxdStore::RemoveTxdSlot(HudTXD); + + debug("Reloading HUD.TXD...\n"); + + HudTXD = CTxdStore::AddTxdSlot("hud"); + CTxdStore::LoadTxd(HudTXD, "MODELS/HUD.TXD"); + CTxdStore::AddRef(HudTXD); + CTxdStore::PopCurrentTxd(); + CTxdStore::SetCurrentTxd(HudTXD); + + for (int i = 0; i < NUM_HUD_SPRITES; i++) { + Sprites[i].SetTexture(WeaponFilenames[i].name, WeaponFilenames[i].mask); + } +} +#endif + void CHud::Initialise() { m_Wants_To_Draw_Hud = true; @@ -1421,6 +1548,29 @@ void CHud::Initialise() PagerSoundPlayed = 0; PagerXOffset = 150.0f; +#ifdef HUD_AUTO_FADE + m_EnergyLostState = START_FADE_OUT; + m_WantedState = START_FADE_OUT; + m_DisplayScoreState = START_FADE_OUT; + m_WeaponState = START_FADE_OUT; +#else + m_EnergyLostState = FADE_DISABLED; + m_WantedState = FADE_DISABLED; + m_DisplayScoreState = FADE_DISABLED; + m_WeaponState = FADE_DISABLED; +#endif + m_WantedFadeTimer = 0; + m_WantedTimer = 0; + m_EnergyLostFadeTimer = 0; + m_EnergyLostTimer = 0; + m_DisplayScoreFadeTimer = 0; + m_DisplayScoreTimer = 0; + m_WeaponFadeTimer = 0; + m_WeaponTimer = 0; + + m_LastDisplayScore = CWorld::Players[CWorld::PlayerInFocus].m_nVisibleMoney; + m_LastWanted = 0; + CTxdStore::PopCurrentTxd(); } @@ -1444,6 +1594,29 @@ void CHud::ReInitialise() { PagerTimer = 0; PagerSoundPlayed = 0; PagerXOffset = 150.0f; + +#ifdef HUD_AUTO_FADE + m_EnergyLostState = START_FADE_OUT; + m_WantedState = START_FADE_OUT; + m_DisplayScoreState = START_FADE_OUT; + m_WeaponState = START_FADE_OUT; +#else + m_EnergyLostState = FADE_DISABLED; + m_WantedState = FADE_DISABLED; + m_DisplayScoreState = FADE_DISABLED; + m_WeaponState = FADE_DISABLED; +#endif + m_WantedFadeTimer = 0; + m_WantedTimer = 0; + m_EnergyLostFadeTimer = 0; + m_EnergyLostTimer = 0; + m_DisplayScoreFadeTimer = 0; + m_DisplayScoreTimer = 0; + m_WeaponFadeTimer = 0; + m_WeaponTimer = 0; + + m_LastDisplayScore = CWorld::Players[CWorld::PlayerInFocus].m_nVisibleMoney; + m_LastWanted = 0; } wchar LastBigMessage[6][128]; @@ -1540,3 +1713,106 @@ void CHud::Shutdown() int HudTXD = CTxdStore::FindTxdSlot("hud"); CTxdStore::RemoveTxdSlot(HudTXD); } + +float CHud::DrawFadeState(DRAW_FADE_STATE fadingElement, int forceFadingIn) +{ + float alpha = 255.0f; + uint32 operation, timer; + int32 fadeTimer; + + switch (fadingElement) { + case HUD_WANTED_FADING: + fadeTimer = m_WantedFadeTimer; + operation = m_WantedState; + timer = m_WantedTimer; + break; + case HUD_ENERGY_FADING: + fadeTimer = m_EnergyLostFadeTimer; + operation = m_EnergyLostState; + timer = m_EnergyLostTimer; + break; + case HUD_SCORE_FADING: + fadeTimer = m_DisplayScoreFadeTimer; + operation = m_DisplayScoreState; + timer = m_DisplayScoreTimer; + break; + case HUD_WEAPON_FADING: + fadeTimer = m_WeaponFadeTimer; + operation = m_WeaponState; + timer = m_WeaponTimer; + break; + default: + break; + } + if (forceFadingIn) { + switch (operation) { + case FADED_OUT: + fadeTimer = 0; + case START_FADE_OUT: + case FADING_OUT: + timer = 5; + operation = FADING_IN; + break; + default: + break; + } + } + if (operation != FADED_OUT && operation != FADE_DISABLED) { + switch (operation) { + case START_FADE_OUT: + fadeTimer = 1000; + alpha = 255.0f; + if (timer > 10000) { + fadeTimer = 3000; + operation = FADING_OUT; + } + break; + case FADING_IN: + fadeTimer += CTimer::GetTimeStepInMilliseconds(); + if (fadeTimer > 1000.0f) { + operation = START_FADE_OUT; + fadeTimer = 1000; + } + alpha = fadeTimer / 1000.0f * 255.0f; + break; + case FADING_OUT: + fadeTimer -= CTimer::GetTimeStepInMilliseconds(); + if (fadeTimer < 0.0f) { + fadeTimer = 0; + operation = FADED_OUT; + } + alpha = fadeTimer / 1000.0f * 255.0f; + break; + default: + break; + } + timer += CTimer::GetTimeStepInMilliseconds(); + } + + switch (fadingElement) { + case HUD_WANTED_FADING: + m_WantedFadeTimer = fadeTimer; + m_WantedState = operation; + m_WantedTimer = timer; + break; + case HUD_ENERGY_FADING: + m_EnergyLostFadeTimer = fadeTimer; + m_EnergyLostState = operation; + m_EnergyLostTimer = timer; + break; + case HUD_SCORE_FADING: + m_DisplayScoreFadeTimer = fadeTimer; + m_DisplayScoreState = operation; + m_DisplayScoreTimer = timer; + break; + case HUD_WEAPON_FADING: + m_WeaponFadeTimer = fadeTimer; + m_WeaponState = operation; + m_WeaponTimer = timer; + break; + default: + break; + } + + return clamp(alpha, 0.0f, 255.0f); +} diff --git a/src/render/Hud.h b/src/render/Hud.h index 701e47e2..db92e32c 100644 --- a/src/render/Hud.h +++ b/src/render/Hud.h @@ -9,6 +9,25 @@ enum eItems ITEM_RADAR = 8 }; +// Thanks for vague name, R* +enum DRAW_FADE_STATE +{ + HUD_WANTED_FADING = 0, + HUD_ENERGY_FADING, + HUD_SCORE_FADING, + HUD_WEAPON_FADING, +}; + +// My name +enum eFadeOperation +{ + FADED_OUT = 0, + START_FADE_OUT, + FADING_IN, + FADING_OUT, + FADE_DISABLED = 5, +}; + enum eSprites { HUD_FIST, @@ -32,6 +51,10 @@ enum eSprites NUM_HUD_SPRITES, }; +// TODO(Miami): Make those 0.7f - 1.25f once fonts have been ported +#define HUD_TEXT_SCALE_X 0.8f +#define HUD_TEXT_SCALE_Y 1.35f + class CHud { public: @@ -82,10 +105,29 @@ public: static int16 PagerTimer; static int16 PagerOn; + static uint32 m_WantedFadeTimer; + static uint32 m_WantedState; + static uint32 m_WantedTimer; + static uint32 m_EnergyLostFadeTimer; + static uint32 m_EnergyLostState; + static uint32 m_EnergyLostTimer; + static uint32 m_DisplayScoreFadeTimer; + static uint32 m_DisplayScoreState; + static uint32 m_DisplayScoreTimer; + static uint32 m_WeaponFadeTimer; + static uint32 m_WeaponState; + static uint32 m_WeaponTimer; + + static uint32 m_LastDisplayScore; + static uint32 m_LastWanted; + public: static void Draw(); static void DrawAfterFade(); static void GetRidOfAllHudMessages(); +#ifdef RELOADABLES + static void ReloadTXD(); +#endif static void Initialise(); static void ReInitialise(); static void SetBigMessage(wchar *message, int16 style); @@ -95,4 +137,5 @@ public: static void SetVehicleName(wchar *name); static void SetZoneName(wchar *name); static void Shutdown(); + static float DrawFadeState(DRAW_FADE_STATE, int); }; diff --git a/src/render/Occlusion.cpp b/src/render/Occlusion.cpp index b33b1d01..1c4e4266 100644 --- a/src/render/Occlusion.cpp +++ b/src/render/Occlusion.cpp @@ -2,6 +2,42 @@ #include "Occlusion.h" +int32 COcclusion::NumOccludersOnMap; +int16 COcclusion::FarAwayList; +int16 COcclusion::NearbyList; +int16 COcclusion::ListWalkThroughFA; +int16 COcclusion::PreviousListWalkThroughFA; +COccluder COcclusion::aOccluders[NUMOCCLUSIONVOLUMES]; + +void +COcclusion::Init(void) +{ + NumOccludersOnMap = 0; + FarAwayList = -1; + NearbyList = -1; + ListWalkThroughFA = -1; + PreviousListWalkThroughFA = -1; +} + +void +COcclusion::AddOne(float x, float y, float z, float width, float length, float height, float angle) +{ + if(NumOccludersOnMap >= NUMOCCLUSIONVOLUMES) + return; + + aOccluders[NumOccludersOnMap].x = x; + aOccluders[NumOccludersOnMap].y = y; + aOccluders[NumOccludersOnMap].z = z; + aOccluders[NumOccludersOnMap].width = width; + aOccluders[NumOccludersOnMap].length = length; + aOccluders[NumOccludersOnMap].height = height; + while(angle < 0.0f) angle += 360.0f; + while(angle > 360.0f) angle -= 360.0f; + aOccluders[NumOccludersOnMap].angle = angle * UINT16_MAX/360.0f; + aOccluders[NumOccludersOnMap].listIndex = FarAwayList; + FarAwayList = NumOccludersOnMap++; +} + void COcclusion::ProcessBeforeRendering(void) { diff --git a/src/render/Occlusion.h b/src/render/Occlusion.h index 977649b8..ac0ede5e 100644 --- a/src/render/Occlusion.h +++ b/src/render/Occlusion.h @@ -1,7 +1,26 @@ #pragma once +class COccluder +{ +public: + int16 width, length, height; + int16 x, y, z; + uint16 angle; + int16 listIndex; +}; + class COcclusion { public: + static int32 NumOccludersOnMap; + static int16 FarAwayList; + static int16 NearbyList; + static int16 ListWalkThroughFA; + static int16 PreviousListWalkThroughFA; + + static COccluder aOccluders[NUMOCCLUSIONVOLUMES]; + + static void Init(void); + static void AddOne(float x, float y, float z, float width, float length, float height, float angle); static void ProcessBeforeRendering(void); }; diff --git a/src/render/Particle.cpp b/src/render/Particle.cpp index e73cd9a7..5f37bdc6 100644 --- a/src/render/Particle.cpp +++ b/src/render/Particle.cpp @@ -11,6 +11,7 @@ #include "AudioScriptObject.h" #include "ParticleObject.h" #include "Particle.h" +#include "soundlist.h" #define MAX_PARTICLES_ON_SCREEN (1000) @@ -1268,7 +1269,7 @@ void CParticle::Update() nil, particle->m_fSize, color, particle->m_nRotationStep, 0, 0, 0); - PlayOneShotScriptObject(_SCRSOUND_BULLET_SHELL_HIT_GROUND_1, particle->m_vecPosition); + PlayOneShotScriptObject(SCRIPT_SOUND_GUNSHELL_DROP, particle->m_vecPosition); } break; @@ -1287,7 +1288,7 @@ void CParticle::Update() nil, particle->m_fSize, color, 0, 0, 0, 0); - PlayOneShotScriptObject(_SCRSOUND_BULLET_SHELL_HIT_GROUND_2, particle->m_vecPosition); + PlayOneShotScriptObject(SCRIPT_SOUND_GUNSHELL_DROP_SOFT, particle->m_vecPosition); } break; diff --git a/src/render/Renderer.cpp b/src/render/Renderer.cpp index 406edc9f..f149c6fb 100644 --- a/src/render/Renderer.cpp +++ b/src/render/Renderer.cpp @@ -143,7 +143,8 @@ CRenderer::RenderOneNonRoad(CEntity *e) resetLights = e->SetupLighting(); if(e->IsVehicle()){ - CVisibilityPlugins::SetupVehicleVariables(e->GetClump()); + // unfortunately can't use GetClump here + CVisibilityPlugins::SetupVehicleVariables((RpClump*)e->m_rwObject); CVisibilityPlugins::InitAlphaAtomicList(); } @@ -1244,9 +1245,11 @@ CRenderer::ShouldModelBeStreamed(CEntity *ent, const CVector &campos) void CRenderer::RemoveVehiclePedLights(CEntity *ent, bool reset) { - if(ent->bRenderScorched) - return; - CPointLights::RemoveLightsAffectingObject(); - if(reset) - ReSetAmbientAndDirectionalColours(); + if(!ent->bRenderScorched){ + CPointLights::RemoveLightsAffectingObject(); + if(reset) + ReSetAmbientAndDirectionalColours(); + } + SetAmbientColours(); + DeActivateDirectional(); } diff --git a/src/render/Shadows.cpp b/src/render/Shadows.cpp index 69f9dce0..fac35aeb 100644 --- a/src/render/Shadows.cpp +++ b/src/render/Shadows.cpp @@ -18,6 +18,7 @@ #endif #include "PointLights.h" #include "SpecialFX.h" +#include "Script.h" #include "Shadows.h" #ifdef DEBUGMENU @@ -642,12 +643,12 @@ CShadows::StoreShadowForPole(CEntity *pPole, float fOffsetX, float fOffsetY, flo PolePos.y += fOffsetX * pPole->GetRight().y + fOffsetY * pPole->GetForward().y; PolePos.z += fOffsetZ; - PolePos.x += -CTimeCycle::GetSunPosition().x * (fPoleHeight / 2); - PolePos.y += -CTimeCycle::GetSunPosition().y * (fPoleHeight / 2); + PolePos.x += -CTimeCycle::GetSunDirection().x * (fPoleHeight / 2); + PolePos.y += -CTimeCycle::GetSunDirection().y * (fPoleHeight / 2); StoreStaticShadow((uintptr)pPole + nID + _TODOCONST(51), SHADOWTYPE_DARK, gpPostShadowTex, &PolePos, - -CTimeCycle::GetSunPosition().x * (fPoleHeight / 2), - -CTimeCycle::GetSunPosition().y * (fPoleHeight / 2), + -CTimeCycle::GetSunDirection().x * (fPoleHeight / 2), + -CTimeCycle::GetSunDirection().y * (fPoleHeight / 2), CTimeCycle::GetShadowSideX() * fPoleWidth, CTimeCycle::GetShadowSideY() * fPoleWidth, 2 * (int32)((pPole->GetUp().z - 0.5f) * CTimeCycle::GetShadowStrength() * 2.0f) / 3, @@ -1766,6 +1767,6 @@ CShadows::RenderIndicatorShadow(uint32 nID, uint8 ShadowType, RwTexture *pTextur ASSERT(pPosn != NULL); C3dMarkers::PlaceMarkerSet(nID, _TODOCONST(4), *pPosn, Max(fFrontX, -fSideY), - 0, 128, 255, 128, - 2048, 0.2f, 0); + SPHERE_MARKER_R, SPHERE_MARKER_G, SPHERE_MARKER_B, + SPHERE_MARKER_A, SPHERE_MARKER_PULSE_PERIOD, 0.2f, 0); } diff --git a/src/render/Skidmarks.cpp b/src/render/Skidmarks.cpp index 7f057319..961c38a6 100644 --- a/src/render/Skidmarks.cpp +++ b/src/render/Skidmarks.cpp @@ -199,8 +199,8 @@ CSkidmarks::RegisterOne(uintptr id, CVector pos, float fwdX, float fwdY, bool *i aSkidmarks[i].m_pos[aSkidmarks[i].m_last] = pos; CVector2D dist = aSkidmarks[i].m_pos[aSkidmarks[i].m_last] - aSkidmarks[i].m_pos[aSkidmarks[i].m_last-1]; - dist.NormaliseSafe(); - fwd.NormaliseSafe(); + dist.Normalise(); + fwd.Normalise(); CVector2D right(dist.y, -dist.x); float turn = DotProduct2D(fwd, right); turn = Abs(turn) + 1.0f; diff --git a/src/render/SpecialFX.cpp b/src/render/SpecialFX.cpp index 7e08fbad..79ae21a5 100644 --- a/src/render/SpecialFX.cpp +++ b/src/render/SpecialFX.cpp @@ -28,6 +28,7 @@ RwImVertexIndex StreakIndexList[12]; RwIm3DVertex TraceVertices[6]; RwImVertexIndex TraceIndexList[12]; +bool CSpecialFX::bSnapShotActive; void CSpecialFX::Init(void) diff --git a/src/render/SpecialFX.h b/src/render/SpecialFX.h index 2d9f18b1..7bc3750a 100644 --- a/src/render/SpecialFX.h +++ b/src/render/SpecialFX.h @@ -3,6 +3,8 @@ class CSpecialFX { public: + static bool bSnapShotActive; + static void Render(void); static void Update(void); static void Init(void); diff --git a/src/render/Sprite.cpp b/src/render/Sprite.cpp index 9631aced..a6d2db7b 100644 --- a/src/render/Sprite.cpp +++ b/src/render/Sprite.cpp @@ -22,8 +22,8 @@ CSprite::CalcHorizonCoors(void) bool CSprite::CalcScreenCoors(const RwV3d &in, RwV3d *out, float *outw, float *outh, bool farclip) { - CVector viewvec = TheCamera.m_viewMatrix * *(CVector*)∈ - *out = *(RwV3d*)&viewvec; + CVector viewvec = TheCamera.m_viewMatrix * in; + *out = viewvec; if(out->z <= CDraw::GetNearClipZ() + 1.0f) return false; if(out->z >= CDraw::GetFarClipZ() && farclip) return false; float recip = 1.0f/out->z; diff --git a/src/render/Sprite2d.cpp b/src/render/Sprite2d.cpp index 189c9797..2675c95f 100644 --- a/src/render/Sprite2d.cpp +++ b/src/render/Sprite2d.cpp @@ -4,11 +4,11 @@ #include "Draw.h" #include "Camera.h" #include "Sprite2d.h" +#include "Font.h" RwIm2DVertex CSprite2d::maVertices[8]; float CSprite2d::RecipNearClip; int32 CSprite2d::mCurrentBank; -RwTexture *CSprite2d::mpBankTextures[10]; int32 CSprite2d::mCurrentSprite[10]; int32 CSprite2d::mBankStart[10]; RwIm2DVertex CSprite2d::maBankVertices[500]; @@ -16,7 +16,7 @@ RwIm2DVertex CSprite2d::maBankVertices[500]; void CSprite2d::SetRecipNearClip(void) { - RecipNearClip = 1.0f / RwCameraGetNearClipPlane(Scene.camera); + // Used but empty in VC, instead they set in InitPerFrame. Isn't that great? } void @@ -24,17 +24,15 @@ CSprite2d::InitPerFrame(void) { int i; + RecipNearClip = 1.0f / RwCameraGetNearClipPlane(Scene.camera); mCurrentBank = 0; for(i = 0; i < 10; i++) mCurrentSprite[i] = 0; - for(i = 0; i < 10; i++) - mpBankTextures[i] = nil; } int32 CSprite2d::GetBank(int32 n, RwTexture *tex) { - mpBankTextures[mCurrentBank] = tex; mCurrentSprite[mCurrentBank] = 0; mBankStart[mCurrentBank+1] = mBankStart[mCurrentBank] + n; return mCurrentBank++; @@ -59,13 +57,14 @@ CSprite2d::DrawBank(int32 bank) { if(mCurrentSprite[bank] == 0) return; - RwRenderStateSet(rwRENDERSTATETEXTURERASTER, - mpBankTextures[bank] ? RwTextureGetRaster(mpBankTextures[bank]) : nil); + + // This is hacked III function to make it work with VC frontend. + CFont::Sprite[bank].SetRenderState(); RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)TRUE); RwRenderStateSet(rwRENDERSTATETEXTUREFILTER, (void*)rwFILTERLINEAR); RwIm2DRenderPrimitive(rwPRIMTYPETRILIST, &maBankVertices[6*mBankStart[bank]], 6*mCurrentSprite[bank]); mCurrentSprite[bank] = 0; - RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)FALSE); + //RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)FALSE); } diff --git a/src/render/Timecycle.cpp b/src/render/Timecycle.cpp index c120c003..bf55d7bc 100644 --- a/src/render/Timecycle.cpp +++ b/src/render/Timecycle.cpp @@ -175,7 +175,11 @@ CTimeCycle::Initialise(void) bi++; bi++; } - while(work_buff[bi] != '\n') + while(work_buff[bi] != '\n' +#ifdef FIX_BUGS + && work_buff[bi] != '\0' +#endif + ) line[li++] = work_buff[bi++]; line[li] = '\0'; bi++; @@ -350,7 +354,7 @@ CTimeCycle::Update(void) m_CurrentStoredValue = (m_CurrentStoredValue+1)&0xF; float sunAngle = 2*PI*(CClock::GetSeconds()/60.0f + CClock::GetMinutes() + CClock::GetHours()*60)/(24*60); - CVector &sunPos = GetSunPosition(); + CVector &sunPos = GetSunDirection(); sunPos.x = Sin(sunAngle); sunPos.y = 1.0f; sunPos.z = 0.2f - Cos(sunAngle); diff --git a/src/render/Timecycle.h b/src/render/Timecycle.h index dc52d493..60c9e29f 100644 --- a/src/render/Timecycle.h +++ b/src/render/Timecycle.h @@ -155,7 +155,7 @@ public: static float GetSpriteSize(void) { return m_fCurrentSpriteSize; } static int GetShadowStrength(void) { return m_nCurrentShadowStrength; } static int GetLightShadowStrength(void) { return m_nCurrentLightShadowStrength; } - static int GetLightOnGroundBrightness(void) { return m_fCurrentLightsOnGroundBrightness; } + static float GetLightOnGroundBrightness(void) { return m_fCurrentLightsOnGroundBrightness; } static float GetFarClip(void) { return m_fCurrentFarClip; } static float GetFogStart(void) { return m_fCurrentFogStart; } @@ -180,7 +180,7 @@ public: static void Initialise(void); static void Update(void); - static CVector &GetSunPosition(void) { return m_VectorToSun[m_CurrentStoredValue]; } + static CVector &GetSunDirection(void) { return m_VectorToSun[m_CurrentStoredValue]; } static float GetShadowFrontX(void) { return m_fShadowFrontX[m_CurrentStoredValue]; } static float GetShadowFrontY(void) { return m_fShadowFrontY[m_CurrentStoredValue]; } static float GetShadowSideX(void) { return m_fShadowSideX[m_CurrentStoredValue]; } diff --git a/src/render/Weather.cpp b/src/render/Weather.cpp index 25e67281..324c63ea 100644 --- a/src/render/Weather.cpp +++ b/src/render/Weather.cpp @@ -8,6 +8,7 @@ #include "DMAudio.h" #include "General.h" #include "Pad.h" +#include "PlayerPed.h" #include "Particle.h" #include "RenderBuffer.h" #include "Stats.h" @@ -17,6 +18,7 @@ #include "Vehicle.h" #include "World.h" #include "ZoneCull.h" +#include "SpecialFX.h" int32 CWeather::SoundHandle = -1; @@ -40,41 +42,60 @@ float CWeather::Rain; float CWeather::InterpolationValue; float CWeather::WetRoads; float CWeather::Rainbow; +float CWeather::SunGlare; +float CWeather::WindClipped; +float CWeather::TrafficLightBrightness; bool CWeather::bScriptsForceRain; -bool CWeather::Stored_StateStored; - -float CWeather::Stored_InterpolationValue; -int16 CWeather::Stored_OldWeatherType; -int16 CWeather::Stored_NewWeatherType; -float CWeather::Stored_Rain; tRainStreak Streaks[NUM_RAIN_STREAKS]; const int16 WeatherTypesList[] = { + WEATHER_EXTRA_SUNNY, WEATHER_EXTRA_SUNNY, WEATHER_EXTRA_SUNNY, WEATHER_EXTRA_SUNNY, + WEATHER_EXTRA_SUNNY, WEATHER_EXTRA_SUNNY, WEATHER_EXTRA_SUNNY, WEATHER_EXTRA_SUNNY, + WEATHER_SUNNY, WEATHER_SUNNY, WEATHER_SUNNY, WEATHER_EXTRA_SUNNY, + WEATHER_EXTRA_SUNNY, WEATHER_EXTRA_SUNNY, WEATHER_SUNNY, WEATHER_SUNNY, + WEATHER_SUNNY, WEATHER_EXTRA_SUNNY, WEATHER_EXTRA_SUNNY, WEATHER_EXTRA_SUNNY, + WEATHER_EXTRA_SUNNY, WEATHER_SUNNY, WEATHER_SUNNY, WEATHER_EXTRA_SUNNY, + WEATHER_EXTRA_SUNNY, WEATHER_EXTRA_SUNNY, WEATHER_EXTRA_SUNNY, WEATHER_EXTRA_SUNNY, + WEATHER_EXTRA_SUNNY, WEATHER_EXTRA_SUNNY, WEATHER_EXTRA_SUNNY, WEATHER_EXTRA_SUNNY, + WEATHER_EXTRA_SUNNY, WEATHER_EXTRA_SUNNY, WEATHER_SUNNY, WEATHER_SUNNY, WEATHER_SUNNY, WEATHER_SUNNY, WEATHER_SUNNY, WEATHER_SUNNY, - WEATHER_SUNNY, WEATHER_SUNNY, WEATHER_SUNNY, WEATHER_SUNNY, - WEATHER_SUNNY, WEATHER_SUNNY, WEATHER_SUNNY, WEATHER_SUNNY, - WEATHER_SUNNY, WEATHER_SUNNY, WEATHER_SUNNY, WEATHER_SUNNY, - WEATHER_CLOUDY, WEATHER_CLOUDY, WEATHER_RAINY, WEATHER_RAINY, + WEATHER_SUNNY, WEATHER_SUNNY, WEATHER_SUNNY, WEATHER_CLOUDY, + WEATHER_RAINY, WEATHER_RAINY, WEATHER_RAINY, WEATHER_RAINY, WEATHER_CLOUDY, WEATHER_SUNNY, WEATHER_SUNNY, WEATHER_SUNNY, - WEATHER_CLOUDY, WEATHER_FOGGY, WEATHER_FOGGY, WEATHER_CLOUDY, - WEATHER_SUNNY, WEATHER_SUNNY, WEATHER_CLOUDY, WEATHER_CLOUDY, + WEATHER_SUNNY, WEATHER_EXTRA_SUNNY, WEATHER_EXTRA_SUNNY, WEATHER_EXTRA_SUNNY, + WEATHER_EXTRA_SUNNY, WEATHER_EXTRA_SUNNY, WEATHER_EXTRA_SUNNY, WEATHER_EXTRA_SUNNY, + WEATHER_EXTRA_SUNNY, WEATHER_EXTRA_SUNNY, WEATHER_EXTRA_SUNNY, WEATHER_EXTRA_SUNNY +}; + +const int16 WeatherTypesList_WithHurricanes[] = { + WEATHER_EXTRA_SUNNY, WEATHER_EXTRA_SUNNY, WEATHER_EXTRA_SUNNY, WEATHER_EXTRA_SUNNY, + WEATHER_EXTRA_SUNNY, WEATHER_EXTRA_SUNNY, WEATHER_EXTRA_SUNNY, WEATHER_EXTRA_SUNNY, + WEATHER_SUNNY, WEATHER_SUNNY, WEATHER_SUNNY, WEATHER_EXTRA_SUNNY, + WEATHER_EXTRA_SUNNY, WEATHER_EXTRA_SUNNY, WEATHER_SUNNY, WEATHER_SUNNY, + WEATHER_SUNNY, WEATHER_EXTRA_SUNNY, WEATHER_EXTRA_SUNNY, WEATHER_CLOUDY, + WEATHER_HURRICANE, WEATHER_HURRICANE, WEATHER_CLOUDY, WEATHER_SUNNY, + WEATHER_EXTRA_SUNNY, WEATHER_EXTRA_SUNNY, WEATHER_EXTRA_SUNNY, WEATHER_EXTRA_SUNNY, + WEATHER_EXTRA_SUNNY, WEATHER_EXTRA_SUNNY, WEATHER_EXTRA_SUNNY, WEATHER_EXTRA_SUNNY, + WEATHER_EXTRA_SUNNY, WEATHER_EXTRA_SUNNY, WEATHER_SUNNY, WEATHER_SUNNY, WEATHER_SUNNY, WEATHER_SUNNY, WEATHER_SUNNY, WEATHER_SUNNY, WEATHER_SUNNY, WEATHER_SUNNY, WEATHER_SUNNY, WEATHER_SUNNY, - WEATHER_CLOUDY, WEATHER_CLOUDY, WEATHER_RAINY, WEATHER_RAINY, - WEATHER_CLOUDY, WEATHER_RAINY, WEATHER_CLOUDY, WEATHER_SUNNY, - WEATHER_SUNNY, WEATHER_SUNNY, WEATHER_SUNNY, WEATHER_SUNNY, - WEATHER_SUNNY, WEATHER_SUNNY, WEATHER_SUNNY, WEATHER_SUNNY, - WEATHER_SUNNY, WEATHER_FOGGY, WEATHER_FOGGY, WEATHER_SUNNY, - WEATHER_SUNNY, WEATHER_SUNNY, WEATHER_RAINY, WEATHER_CLOUDY, + WEATHER_CLOUDY, WEATHER_HURRICANE, WEATHER_HURRICANE, WEATHER_HURRICANE, + WEATHER_CLOUDY, WEATHER_SUNNY, WEATHER_SUNNY, WEATHER_SUNNY, + WEATHER_SUNNY, WEATHER_EXTRA_SUNNY, WEATHER_EXTRA_SUNNY, WEATHER_EXTRA_SUNNY, + WEATHER_EXTRA_SUNNY, WEATHER_EXTRA_SUNNY, WEATHER_EXTRA_SUNNY, WEATHER_EXTRA_SUNNY, + WEATHER_EXTRA_SUNNY, WEATHER_EXTRA_SUNNY, WEATHER_EXTRA_SUNNY, WEATHER_EXTRA_SUNNY }; const float Windiness[] = { - 0.0f, // WEATHER_SUNNY + 0.25f,// WEATHER_SUNNY 0.7f, // WEATHER_CLOUDY 1.0f, // WEATHER_RAINY - 0.5f // WEATHER_FOGGY + 0.0f, // WEATHER_FOGGY + 0.0f, // WEATHER_EXTRA_SUNNY + 2.0f, // WEATHER_HURRICANE + 0.0f }; #define MIN_TIME_BETWEEN_LIGHTNING_FLASH_CHANGES (50) @@ -105,10 +126,9 @@ const float Windiness[] = { void CWeather::Init(void) { - NewWeatherType = WEATHER_SUNNY; + NewWeatherType = WEATHER_EXTRA_SUNNY; bScriptsForceRain = false; - OldWeatherType = WEATHER_CLOUDY; - Stored_StateStored = false; + OldWeatherType = WEATHER_EXTRA_SUNNY; InterpolationValue = 0.0f; WhenToPlayLightningSound = 0; WeatherTypeInList = 0; @@ -128,16 +148,8 @@ void CWeather::Update(void) NewWeatherType = ForcedWeatherType; else { WeatherTypeInList = (WeatherTypeInList + 1) % ARRAY_SIZE(WeatherTypesList); - NewWeatherType = WeatherTypesList[WeatherTypeInList]; -#ifdef FIX_BUGS + NewWeatherType = CStats::NoMoreHurricanes ? WeatherTypesList[WeatherTypeInList] : WeatherTypesList_WithHurricanes[WeatherTypeInList]; } - if (NewWeatherType == WEATHER_RAINY) - CStats::mmRain += CGeneral::GetRandomNumber() & 7; -#else - if (NewWeatherType == WEATHER_RAINY) - CStats::mmRain += CGeneral::GetRandomNumber() & 7; - } -#endif } InterpolationValue = fNewInterpolation; if (CPad::GetPad(1)->GetRightShockJustDown()) { @@ -189,14 +201,14 @@ void CWeather::Update(void) } // Wet roads - if (OldWeatherType == WEATHER_RAINY) { - if (NewWeatherType == WEATHER_RAINY) + if (OldWeatherType == WEATHER_RAINY || OldWeatherType == WEATHER_HURRICANE) { + if (NewWeatherType == WEATHER_RAINY || NewWeatherType == WEATHER_HURRICANE) WetRoads = 1.0f; else WetRoads = 1.0f - InterpolationValue; } else { - if (NewWeatherType == WEATHER_RAINY) + if (NewWeatherType == WEATHER_RAINY || NewWeatherType == WEATHER_HURRICANE) WetRoads = InterpolationValue; else WetRoads = 0.0f; @@ -204,10 +216,10 @@ void CWeather::Update(void) // Rain float fNewRain; - if (NewWeatherType == WEATHER_RAINY) { + if (NewWeatherType == WEATHER_RAINY || NewWeatherType == WEATHER_HURRICANE) { // if raining for >1 hour, values: 0, 0.33, 0.66, 0.99, switching every ~16.5s fNewRain = ((uint16)CTimer::GetTimeInMilliseconds() >> 14) * 0.33f; - if (OldWeatherType != WEATHER_RAINY) { + if (OldWeatherType != WEATHER_RAINY && OldWeatherType != WEATHER_HURRICANE) { if (InterpolationValue < 0.4f) // if rain has just started (<24 minutes), always 0.5 fNewRain = 0.5f; @@ -218,19 +230,14 @@ void CWeather::Update(void) } else fNewRain = 0.0f; - if (Rain != fNewRain) { // ok to use comparasion - if (Rain < fNewRain) - Rain = Min(fNewRain, Rain + RAIN_CHANGE_SPEED * CTimer::GetTimeStep()); - else - Rain = Max(fNewRain, Rain - RAIN_CHANGE_SPEED * CTimer::GetTimeStep()); - } + Rain = fNewRain; // Clouds - if (OldWeatherType != WEATHER_SUNNY) + if (OldWeatherType != WEATHER_SUNNY && OldWeatherType != WEATHER_EXTRA_SUNNY) CloudCoverage = 1.0f - InterpolationValue; else CloudCoverage = 0.0f; - if (NewWeatherType != WEATHER_SUNNY) + if (NewWeatherType != WEATHER_SUNNY && OldWeatherType != WEATHER_EXTRA_SUNNY) CloudCoverage += InterpolationValue; // Fog @@ -240,12 +247,77 @@ void CWeather::Update(void) Foggyness = 0.0f; if (NewWeatherType == WEATHER_FOGGY) Foggyness += InterpolationValue; - if (OldWeatherType == WEATHER_RAINY && NewWeatherType == WEATHER_SUNNY && InterpolationValue < 0.5f && CClock::GetHours() > 6 && CClock::GetHours() < 21) + + // Extra Sunnyness + if (OldWeatherType == WEATHER_EXTRA_SUNNY) + ExtraSunnyness = 1.0f - InterpolationValue; + else + ExtraSunnyness = 0.0f; + if (NewWeatherType == WEATHER_EXTRA_SUNNY) + ExtraSunnyness += InterpolationValue; + + // Rainbow + if (OldWeatherType == WEATHER_RAINY && (NewWeatherType == WEATHER_SUNNY || NewWeatherType == WEATHER_EXTRA_SUNNY) && + InterpolationValue < 0.5f && CClock::GetHours() > 6 && CClock::GetHours() < 21) Rainbow = 1.0f - 4.0f * Abs(InterpolationValue - 0.25f) / 4.0f; else Rainbow = 0.0f; + + // Sun Glare + if (OldWeatherType == WEATHER_EXTRA_SUNNY) + SunGlare = 1.0f - InterpolationValue; + else + SunGlare = 0.0f; + if (NewWeatherType == WEATHER_EXTRA_SUNNY) + SunGlare += InterpolationValue; + + if (SunGlare > 0.0f) { + SunGlare *= Min(1.0f, 7.0 * CTimeCycle::GetSunDirection().z); + SunGlare = clamp(SunGlare, 0.0f, 1.0f); + if (!CSpecialFX::bSnapShotActive) + SunGlare *= (1.0f - (CGeneral::GetRandomNumber()&0x1F)*0.007f); + } + Wind = InterpolationValue * Windiness[NewWeatherType] + (1.0f - InterpolationValue) * Windiness[OldWeatherType]; + WindClipped = Max(1.0f, Wind); + + if (CClock::GetHours() == 20) + TrafficLightBrightness = CClock::GetMinutes() / 60.0f; + else if (CClock::GetHours() > 6 && CClock::GetHours() < 20) + TrafficLightBrightness = 0.0f; + else if (CClock::GetHours() == 6) + TrafficLightBrightness = 1.0f - CClock::GetMinutes() / 60.0f; + else + TrafficLightBrightness = 1.0f; + TrafficLightBrightness = Max(WetRoads, TrafficLightBrightness); + TrafficLightBrightness = Max(Rain, TrafficLightBrightness); + AddRain(); + + if ((NewWeatherType == WEATHER_SUNNY || NewWeatherType == WEATHER_EXTRA_SUNNY) && + !CGame::IsInInterior() && !CCutsceneMgr::IsRunning() && (CTimer::GetFrameCounter() & 7) == 0) { +#ifdef FIX_BUGS + if (FindPlayerPed() && (!FindPlayerPed()->CheckIfInTheAir() || FindPlayerPed()->CheckIfInTheAir() && FindPlayerPed()->GetPosition().z < 7.5f && + CClock::GetHours() > 6 && CClock::GetHours() < 18)) +#else + if (!FindPlayerPed()->CheckIfInTheAir() || FindPlayerPed()->CheckIfInTheAir() && FindPlayerPed()->GetPosition().z < 7.5f && + CClock::GetHours() > 6 && CClock::GetHours() < 18) +#endif + AddHeatHaze(); + } + + if ((NewWeatherType == WEATHER_SUNNY || NewWeatherType == WEATHER_EXTRA_SUNNY) && !CGame::IsInInterior() && !CCutsceneMgr::IsRunning()) + AddBeastie(); +} + +void CWeather::AddHeatHaze() +{ + /* TODO(MIAMI) */ +} + +void CWeather::AddBeastie() +{ + /* TODO(MIAMI) */ } void CWeather::ForceWeather(int16 weather) @@ -511,23 +583,3 @@ void CWeather::RenderRainStreaks(void) TempBufferVerticesStored = 0; TempBufferIndicesStored = 0; } - -void CWeather::StoreWeatherState() -{ - Stored_StateStored = true; - Stored_InterpolationValue = InterpolationValue; - Stored_Rain = Rain; - Stored_NewWeatherType = NewWeatherType; - Stored_OldWeatherType = OldWeatherType; -} - -void CWeather::RestoreWeatherState() -{ -#ifdef FIX_BUGS // it's not used anyway though - Stored_StateStored = false; -#endif - InterpolationValue = Stored_InterpolationValue; - Rain = Stored_Rain; - NewWeatherType = Stored_NewWeatherType; - OldWeatherType = Stored_OldWeatherType; -} diff --git a/src/render/Weather.h b/src/render/Weather.h index 4bf2fd8f..bd9b9603 100644 --- a/src/render/Weather.h +++ b/src/render/Weather.h @@ -1,21 +1,17 @@ enum { - WEATHER_SUNNY, + WEATHER_RANDOM = -1, + WEATHER_SUNNY = 0, WEATHER_CLOUDY, WEATHER_RAINY, - WEATHER_FOGGY + WEATHER_FOGGY, + WEATHER_EXTRA_SUNNY, + WEATHER_HURRICANE, + WEATHER_TOTAL }; class CWeather { public: - enum { - WEATHER_RANDOM = -1, - WEATHER_SUNNY = 0, - WEATHER_CLOUDY = 1, - WEATHER_RAINY = 2, - WEATHER_FOGGY = 3, - WEATHER_TOTAL = 4 - }; static int32 SoundHandle; static int32 WeatherTypeInList; @@ -38,13 +34,11 @@ public: static float InterpolationValue; static float WetRoads; static float Rainbow; + static float SunGlare; + static float WindClipped; + static float TrafficLightBrightness; static bool bScriptsForceRain; - static bool Stored_StateStored; - static float Stored_InterpolationValue; - static int16 Stored_OldWeatherType; - static int16 Stored_NewWeatherType; - static float Stored_Rain; static void RenderRainStreaks(void); static void Update(void); @@ -53,9 +47,9 @@ public: static void ReleaseWeather(); static void ForceWeather(int16); static void ForceWeatherNow(int16); - static void StoreWeatherState(); - static void RestoreWeatherState(); static void AddRain(); + static void AddHeatHaze(); + static void AddBeastie(); }; enum { diff --git a/src/render/WindModifiers.cpp b/src/render/WindModifiers.cpp new file mode 100644 index 00000000..d7405c7a --- /dev/null +++ b/src/render/WindModifiers.cpp @@ -0,0 +1,8 @@ +#include "common.h" +#include "WindModifiers.h" + +int32 +CWindModifiers::FindWindModifier(CVector pos, float *x, float *y) +{ + return 0; +} diff --git a/src/render/WindModifiers.h b/src/render/WindModifiers.h new file mode 100644 index 00000000..b4024343 --- /dev/null +++ b/src/render/WindModifiers.h @@ -0,0 +1,7 @@ +#pragma once + +class CWindModifiers +{ +public: + static int32 FindWindModifier(CVector pos, float *x, float *y); +}; diff --git a/src/rw/Lights.cpp b/src/rw/Lights.cpp index 8f7f92b6..cd45b81f 100644 --- a/src/rw/Lights.cpp +++ b/src/rw/Lights.cpp @@ -86,9 +86,9 @@ SetLightsWithTimeOfDayColour(RpWorld *) RwFrameTransform(RpLightGetFrame(pDirect), &mat, rwCOMBINEREPLACE); } - if(CMenuManager::m_PrefsBrightness > 256){ - float f1 = 2.0f * (CMenuManager::m_PrefsBrightness/256.0f - 1.0f) * 0.6f + 1.0f; - float f2 = 3.0f * (CMenuManager::m_PrefsBrightness/256.0f - 1.0f) * 0.6f + 1.0f; + if(FrontEndMenuManager.m_PrefsBrightness > 256){ + float f1 = 2.0f * (FrontEndMenuManager.m_PrefsBrightness/256.0f - 1.0f) * 0.6f + 1.0f; + float f2 = 3.0f * (FrontEndMenuManager.m_PrefsBrightness/256.0f - 1.0f) * 0.6f + 1.0f; AmbientLightColourForFrame.red = Min(1.0f, AmbientLightColourForFrame.red * f2); AmbientLightColourForFrame.green = Min(1.0f, AmbientLightColourForFrame.green * f2); diff --git a/src/rw/RwHelper.cpp b/src/rw/RwHelper.cpp index 91916df3..a87874d7 100644 --- a/src/rw/RwHelper.cpp +++ b/src/rw/RwHelper.cpp @@ -60,6 +60,16 @@ void FlushObrsPrintfs() void * RwMallocAlign(RwUInt32 size, RwUInt32 align) { +#ifdef FIX_BUGS + uintptr ptralign = align-1; + void *mem = (void *)malloc(size + sizeof(uintptr) + ptralign); + + ASSERT(mem != nil); + + void *addr = (void *)((((uintptr)mem) + sizeof(uintptr) + ptralign) & ~ptralign); + + ASSERT(addr != nil); +#else void *mem = (void *)malloc(size + align); ASSERT(mem != nil); @@ -67,6 +77,7 @@ RwMallocAlign(RwUInt32 size, RwUInt32 align) void *addr = (void *)((((uintptr)mem) + align) & ~(align - 1)); ASSERT(addr != nil); +#endif *(((void **)addr) - 1) = mem; diff --git a/src/rw/VisibilityPlugins.cpp b/src/rw/VisibilityPlugins.cpp index 5a94e8f6..cff1ff16 100644 --- a/src/rw/VisibilityPlugins.cpp +++ b/src/rw/VisibilityPlugins.cpp @@ -139,6 +139,8 @@ static float PitchToCamera; void CVisibilityPlugins::SetupVehicleVariables(RpClump *vehicle) { + if (RwObjectGetType((RwObject*)vehicle) != rpCLUMP) + return; DistToCameraSq = GetDistanceSquaredFromCamera(RpClumpGetFrame(vehicle)); RwV3d distToCam; RwV3dSub(&distToCam, ms_pCameraPosn, &RwFrameGetMatrix(RpClumpGetFrame(vehicle))->pos); diff --git a/src/save/GenericGameStorage.cpp b/src/save/GenericGameStorage.cpp index 1afa8165..839ad8b9 100644 --- a/src/save/GenericGameStorage.cpp +++ b/src/save/GenericGameStorage.cpp @@ -29,6 +29,7 @@ #include "Radar.h" #include "Restart.h" #include "Script.h" +#include "SetPieces.h" #include "Stats.h" #include "Streaming.h" #include "Timer.h" @@ -206,6 +207,7 @@ GenericSave(int file) WriteSaveDataBlock(cAudioScriptObject::SaveAllAudioScriptObjects); WriteSaveDataBlock(CWorld::Players[CWorld::PlayerInFocus].SavePlayerInfo); WriteSaveDataBlock(CStats::SaveStats); + WriteSaveDataBlock(CSetPieces::Save); WriteSaveDataBlock(CStreaming::MemoryCardSave); WriteSaveDataBlock(CPedType::Save); @@ -337,12 +339,14 @@ GenericLoad() LoadSaveDataBlock(); ReadDataFromBlock("Loading Stats \n", CStats::LoadStats); LoadSaveDataBlock(); + ReadDataFromBlock("Loading Set Pieces \n", CSetPieces::Load); + LoadSaveDataBlock(); ReadDataFromBlock("Loading Streaming Stuff \n", CStreaming::MemoryCardLoad); LoadSaveDataBlock(); ReadDataFromBlock("Loading PedType Stuff \n", CPedType::Load); - DMAudio.SetMusicMasterVolume(CMenuManager::m_PrefsMusicVolume); - DMAudio.SetEffectsMasterVolume(CMenuManager::m_PrefsSfxVolume); + DMAudio.SetMusicMasterVolume(FrontEndMenuManager.m_PrefsMusicVolume); + DMAudio.SetEffectsMasterVolume(FrontEndMenuManager.m_PrefsSfxVolume); if (!CloseFile(file)) { PcSaveHelper.nErrorCode = SAVESTATUS_ERR_LOAD_CLOSE; return false; diff --git a/src/save/GenericGameStorage.h b/src/save/GenericGameStorage.h index b913c305..2d83385b 100644 --- a/src/save/GenericGameStorage.h +++ b/src/save/GenericGameStorage.h @@ -1,5 +1,6 @@ #pragma once +#include "Game.h" #include "PCSave.h" #define SLOT_COUNT (8) @@ -40,4 +41,4 @@ extern uint32 TimeToStayFadedBeforeFadeOut; extern char SaveFileNameJustSaved[260]; // 8F2570 -const char TopLineEmptyFile[] = "THIS FILE IS NOT VALID YET"; \ No newline at end of file +const char TopLineEmptyFile[] = "THIS FILE IS NOT VALID YET"; diff --git a/src/skel/glfw/glfw.cpp b/src/skel/glfw/glfw.cpp index c60c5cd9..407418c7 100644 --- a/src/skel/glfw/glfw.cpp +++ b/src/skel/glfw/glfw.cpp @@ -176,7 +176,7 @@ psCameraBeginUpdate(RwCamera *camera) void psCameraShowRaster(RwCamera *camera) { - if (CMenuManager::m_PrefsVsync) + if (FrontEndMenuManager.m_PrefsVsync) RwCameraShowRaster(camera, PSGLOBAL(window), rwRASTERFLIPWAITVSYNC); else RwCameraShowRaster(camera, PSGLOBAL(window), rwRASTERFLIPDONTWAIT); @@ -274,7 +274,7 @@ psNativeTextureSupport(void) ***************************************************************************** */ RwBool -psInitialise(void) +psInitialize(void) { PsGlobal.lastMousePos.x = PsGlobal.lastMousePos.y = 0.0f; @@ -789,7 +789,7 @@ RwBool _psSetVideoMode(RwInt32 subSystem, RwInt32 videoMode) useDefault = TRUE; - if ( RsEventHandler(rsRWINITIALISE, &openParams) == rsEVENTERROR ) + if ( RsEventHandler(rsRWINITIALIZE, &openParams) == rsEVENTERROR ) return FALSE; RwInitialised = TRUE; @@ -944,7 +944,7 @@ void InitialiseLanguage() || primLayout == LANG_GERMAN ) { CGame::nastyGame = false; - CMenuManager::m_PrefsAllowNastyGame = false; + FrontEndMenuManager.m_PrefsAllowNastyGame = false; CGame::germanGame = true; } @@ -953,7 +953,7 @@ void InitialiseLanguage() || primLayout == LANG_FRENCH ) { CGame::nastyGame = false; - CMenuManager::m_PrefsAllowNastyGame = false; + FrontEndMenuManager.m_PrefsAllowNastyGame = false; CGame::frenchGame = true; } @@ -964,7 +964,7 @@ void InitialiseLanguage() #ifdef NASTY_GAME CGame::nastyGame = true; - CMenuManager::m_PrefsAllowNastyGame = true; + FrontEndMenuManager.m_PrefsAllowNastyGame = true; CGame::noProstitutes = false; #endif @@ -999,33 +999,33 @@ void InitialiseLanguage() } } - CMenuManager::OS_Language = primUserLCID; + FrontEndMenuManager.OS_Language = primUserLCID; switch ( lang ) { case LANG_GERMAN: { - CMenuManager::m_PrefsLanguage = LANGUAGE_GERMAN; + FrontEndMenuManager.m_PrefsLanguage = LANGUAGE_GERMAN; break; } case LANG_SPANISH: { - CMenuManager::m_PrefsLanguage = LANGUAGE_SPANISH; + FrontEndMenuManager.m_PrefsLanguage = LANGUAGE_SPANISH; break; } case LANG_FRENCH: { - CMenuManager::m_PrefsLanguage = LANGUAGE_FRENCH; + FrontEndMenuManager.m_PrefsLanguage = LANGUAGE_FRENCH; break; } case LANG_ITALIAN: { - CMenuManager::m_PrefsLanguage = LANGUAGE_ITALIAN; + FrontEndMenuManager.m_PrefsLanguage = LANGUAGE_ITALIAN; break; } default: { - CMenuManager::m_PrefsLanguage = LANGUAGE_AMERICAN; + FrontEndMenuManager.m_PrefsLanguage = LANGUAGE_AMERICAN; break; } } @@ -1312,7 +1312,7 @@ main(int argc, char *argv[]) * Initialize the platform independent data. * This will in turn initialize the platform specific data... */ - if( RsEventHandler(rsINITIALISE, nil) == rsEVENTERROR ) + if( RsEventHandler(rsINITIALIZE, nil) == rsEVENTERROR ) { return FALSE; } @@ -1355,7 +1355,7 @@ main(int argc, char *argv[]) /* * Initialize the 3D (RenderWare) components of the app... */ - if( rsEVENTERROR == RsEventHandler(rsRWINITIALISE, &openParams) ) + if( rsEVENTERROR == RsEventHandler(rsRWINITIALIZE, &openParams) ) { RsEventHandler(rsTERMINATE, nil); @@ -1486,7 +1486,7 @@ main(int argc, char *argv[]) FrontEndMenuManager.m_bGameNotLoaded = true; - CMenuManager::m_bStartUpFrontEndRequested = true; + FrontEndMenuManager.m_bStartUpFrontEndRequested = true; if ( defaultFullscreenRes ) { @@ -1535,7 +1535,7 @@ main(int argc, char *argv[]) float ms = (float)CTimer::GetCurrentTimeInCycles() / (float)CTimer::GetCyclesPerMillisecond(); if ( RwInitialised ) { - if (!CMenuManager::m_PrefsFrameLimiter || (1000.0f / (float)RsGlobal.maxFPS) < ms) + if (!FrontEndMenuManager.m_PrefsFrameLimiter || (1000.0f / (float)RsGlobal.maxFPS) < ms) RsEventHandler(rsIDLE, (void *)TRUE); } break; @@ -1546,7 +1546,7 @@ main(int argc, char *argv[]) float ms = (float)CTimer::GetCurrentTimeInCycles() / (float)CTimer::GetCyclesPerMillisecond(); if (RwInitialised) { - if (!CMenuManager::m_PrefsFrameLimiter || (1000.0f / (float)RsGlobal.maxFPS) < ms) + if (!FrontEndMenuManager.m_PrefsFrameLimiter || (1000.0f / (float)RsGlobal.maxFPS) < ms) RsEventHandler(rsANIMVIEWER, (void*)TRUE); } break; diff --git a/src/skel/platform.h b/src/skel/platform.h index 65e20673..cbb1be28 100644 --- a/src/skel/platform.h +++ b/src/skel/platform.h @@ -15,7 +15,7 @@ extern RwUInt32 psTimer(void); extern double psTimer(void); #endif -extern RwBool psInitialise(void); +extern RwBool psInitialize(void); extern void psTerminate(void); extern void psCameraShowRaster(RwCamera *camera); diff --git a/src/skel/skeleton.cpp b/src/skel/skeleton.cpp index 5191eda7..073155d6 100644 --- a/src/skel/skeleton.cpp +++ b/src/skel/skeleton.cpp @@ -246,8 +246,8 @@ RsEventHandler(RsEvent event, void *param) result = (rsEVENTPROCESSED); break; - case rsRWINITIALISE: - result = (RsRwInitialise(param) ? + case rsRWINITIALIZE: + result = (RsRwInitialize(param) ? rsEVENTPROCESSED : rsEVENTERROR); break; @@ -256,9 +256,9 @@ RsEventHandler(RsEvent event, void *param) result = (rsEVENTPROCESSED); break; - case rsINITIALISE: + case rsINITIALIZE: result = - (RsInitialise()? rsEVENTPROCESSED : rsEVENTERROR); + (RsInitialize()? rsEVENTPROCESSED : rsEVENTERROR); break; default: @@ -294,7 +294,7 @@ RsRwTerminate(void) ***************************************************************************** */ RwBool -RsRwInitialise(void *displayID) +RsRwInitialize(void *displayID) { RwEngineOpenParams openParams; @@ -383,14 +383,14 @@ RsTerminate(void) ***************************************************************************** */ RwBool -RsInitialise(void) +RsInitialize(void) { /* * Initialize Platform independent data... */ RwBool result; - RsGlobal.appName = RWSTRING("GTA3"); + RsGlobal.appName = RWSTRING("GTA: Vice City"); RsGlobal.maximumWidth = DEFAULT_SCREEN_WIDTH; RsGlobal.maximumHeight = DEFAULT_SCREEN_HEIGHT; RsGlobal.width = DEFAULT_SCREEN_WIDTH; @@ -415,7 +415,7 @@ RsInitialise(void) RsGlobal.pad.inputEventHandler = nil; RsGlobal.pad.used = FALSE; - result = psInitialise(); + result = psInitialize(); return result; } diff --git a/src/skel/skeleton.h b/src/skel/skeleton.h index 8303bd9a..b5ea5abf 100644 --- a/src/skel/skeleton.h +++ b/src/skel/skeleton.h @@ -61,10 +61,10 @@ enum RsEvent _rs_18, _rs_19, _rs_20, - rsRWINITIALISE, + rsRWINITIALIZE, rsRWTERMINATE, rsSELECTDEVICE, - rsINITIALISE, + rsINITIALIZE, rsTERMINATE, rsIDLE, rsFRONTENDIDLE, @@ -241,19 +241,19 @@ extern RsEventStatus RsEventHandler(RsEvent event, void *param); extern RsEventStatus RsKeyboardEventHandler(RsEvent event, void *param); extern RsEventStatus RsPadEventHandler(RsEvent event, void *param); -extern RwBool -RsInitialise(void); +extern RwBool +RsInitialize(void); -extern RwBool +extern RwBool RsRegisterImageLoader(void); -extern RwBool -RsRwInitialise(void *param); +extern RwBool +RsRwInitialize(void *param); -extern RwBool +extern RwBool RsSelectDevice(void); -extern RwBool +extern RwBool RsInputDeviceAttach(RsInputDeviceType inputDevice, RsInputEventHandler inputEventHandler); diff --git a/src/skel/win/gta3.ico b/src/skel/win/gta3.ico deleted file mode 100644 index 2017c811..00000000 Binary files a/src/skel/win/gta3.ico and /dev/null differ diff --git a/src/skel/win/gtavc.ico b/src/skel/win/gtavc.ico new file mode 100644 index 00000000..d253ff2c Binary files /dev/null and b/src/skel/win/gtavc.ico differ diff --git a/src/skel/win/win.cpp b/src/skel/win/win.cpp index f41b9ef8..7de58d87 100644 --- a/src/skel/win/win.cpp +++ b/src/skel/win/win.cpp @@ -221,7 +221,7 @@ psCameraBeginUpdate(RwCamera *camera) void psCameraShowRaster(RwCamera *camera) { - if (CMenuManager::m_PrefsVsync) + if (FrontEndMenuManager.m_PrefsVsync) RwCameraShowRaster(camera, PSGLOBAL(window), rwRASTERFLIPWAITVSYNC); else RwCameraShowRaster(camera, PSGLOBAL(window), rwRASTERFLIPDONTWAIT); @@ -584,7 +584,7 @@ void _psPrintCpuInfo() ***************************************************************************** */ RwBool -psInitialise(void) +psInitialize(void) { PsGlobal.lastMousePos.x = PsGlobal.lastMousePos.y = 0.0f; @@ -1222,6 +1222,16 @@ MainWndProc(HWND window, UINT message, WPARAM wParam, LPARAM lParam) break; } +#ifdef FIX_BUGS // game turns on menu when focus is re-gained rather than lost + case WM_KILLFOCUS: +#else + case WM_SETFOCUS: +#endif + { + CGame::InitAfterFocusLoss(); + break; + } + } /* @@ -1525,7 +1535,7 @@ RwBool _psSetVideoMode(RwInt32 subSystem, RwInt32 videoMode) useDefault = TRUE; - if ( RsEventHandler(rsRWINITIALISE, PSGLOBAL(window)) == rsEVENTERROR ) + if ( RsEventHandler(rsRWINITIALIZE, PSGLOBAL(window)) == rsEVENTERROR ) return FALSE; RwInitialised = TRUE; @@ -1654,7 +1664,7 @@ void InitialiseLanguage() || primLayout == LANG_GERMAN ) { CGame::nastyGame = false; - CMenuManager::m_PrefsAllowNastyGame = false; + FrontEndMenuManager.m_PrefsAllowNastyGame = false; CGame::germanGame = true; } @@ -1663,7 +1673,7 @@ void InitialiseLanguage() || primLayout == LANG_FRENCH ) { CGame::nastyGame = false; - CMenuManager::m_PrefsAllowNastyGame = false; + FrontEndMenuManager.m_PrefsAllowNastyGame = false; CGame::frenchGame = true; } @@ -1674,7 +1684,7 @@ void InitialiseLanguage() #ifdef NASTY_GAME CGame::nastyGame = true; - CMenuManager::m_PrefsAllowNastyGame = true; + FrontEndMenuManager.m_PrefsAllowNastyGame = true; CGame::noProstitutes = false; #endif @@ -1709,33 +1719,33 @@ void InitialiseLanguage() } } - CMenuManager::OS_Language = primUserLCID; + FrontEndMenuManager.OS_Language = primUserLCID; switch ( lang ) { case LANG_GERMAN: { - CMenuManager::m_PrefsLanguage = LANGUAGE_GERMAN; + FrontEndMenuManager.m_PrefsLanguage = LANGUAGE_GERMAN; break; } case LANG_SPANISH: { - CMenuManager::m_PrefsLanguage = LANGUAGE_SPANISH; + FrontEndMenuManager.m_PrefsLanguage = LANGUAGE_SPANISH; break; } case LANG_FRENCH: { - CMenuManager::m_PrefsLanguage = LANGUAGE_FRENCH; + FrontEndMenuManager.m_PrefsLanguage = LANGUAGE_FRENCH; break; } case LANG_ITALIAN: { - CMenuManager::m_PrefsLanguage = LANGUAGE_ITALIAN; + FrontEndMenuManager.m_PrefsLanguage = LANGUAGE_ITALIAN; break; } default: { - CMenuManager::m_PrefsLanguage = LANGUAGE_AMERICAN; + FrontEndMenuManager.m_PrefsLanguage = LANGUAGE_AMERICAN; break; } } @@ -1894,7 +1904,7 @@ WinMain(HINSTANCE instance, * Initialize the platform independent data. * This will in turn initialize the platform specific data... */ - if( RsEventHandler(rsINITIALISE, nil) == rsEVENTERROR ) + if( RsEventHandler(rsINITIALIZE, nil) == rsEVENTERROR ) { return FALSE; } @@ -1960,7 +1970,7 @@ WinMain(HINSTANCE instance, /* * Initialize the 3D (RenderWare) components of the app... */ - if( rsEVENTERROR == RsEventHandler(rsRWINITIALISE, PSGLOBAL(window)) ) + if( rsEVENTERROR == RsEventHandler(rsRWINITIALIZE, PSGLOBAL(window)) ) { DestroyWindow(PSGLOBAL(window)); @@ -2128,7 +2138,7 @@ WinMain(HINSTANCE instance, CoUninitialize(); - if ( CMenuManager::OS_Language == LANG_FRENCH || CMenuManager::OS_Language == LANG_GERMAN ) + if ( FrontEndMenuManager.OS_Language == LANG_FRENCH || FrontEndMenuManager.OS_Language == LANG_GERMAN ) PlayMovieInWindow(cmdShow, "movies\\GTAtitlesGER.mpg"); else PlayMovieInWindow(cmdShow, "movies\\GTAtitles.mpg"); @@ -2179,7 +2189,7 @@ WinMain(HINSTANCE instance, FrontEndMenuManager.m_bGameNotLoaded = true; - CMenuManager::m_bStartUpFrontEndRequested = true; + FrontEndMenuManager.m_bStartUpFrontEndRequested = true; if ( defaultFullscreenRes ) { @@ -2230,7 +2240,7 @@ WinMain(HINSTANCE instance, float ms = (float)CTimer::GetCurrentTimeInCycles() / (float)CTimer::GetCyclesPerMillisecond(); if ( RwInitialised ) { - if (!CMenuManager::m_PrefsFrameLimiter || (1000.0f / (float)RsGlobal.maxFPS) < ms) + if (!FrontEndMenuManager.m_PrefsFrameLimiter || (1000.0f / (float)RsGlobal.maxFPS) < ms) RsEventHandler(rsIDLE, (void *)TRUE); } break; @@ -2241,7 +2251,7 @@ WinMain(HINSTANCE instance, float ms = (float)CTimer::GetCurrentTimeInCycles() / (float)CTimer::GetCyclesPerMillisecond(); if (RwInitialised) { - if (!CMenuManager::m_PrefsFrameLimiter || (1000.0f / (float)RsGlobal.maxFPS) < ms) + if (!FrontEndMenuManager.m_PrefsFrameLimiter || (1000.0f / (float)RsGlobal.maxFPS) < ms) RsEventHandler(rsANIMVIEWER, (void*)TRUE); } break; diff --git a/src/skel/win/win.rc b/src/skel/win/win.rc index 379c473d..9b5aa305 100644 --- a/src/skel/win/win.rc +++ b/src/skel/win/win.rc @@ -42,6 +42,6 @@ END // Icon with lowest ID value placed first to ensure application icon // remains consistent on all systems. -IDI_MAIN_ICON ICON DISCARDABLE "gta3.ico" +IDI_MAIN_ICON ICON DISCARDABLE "gtavc.ico" ///////////////////////////////////////////////////////////////////////////// \ No newline at end of file diff --git a/src/text/Text.cpp b/src/text/Text.cpp index 549f68d9..e092627e 100644 --- a/src/text/Text.cpp +++ b/src/text/Text.cpp @@ -7,30 +7,39 @@ #include "Frontend.h" #include "Messages.h" #include "Text.h" +#include "Timer.h" static wchar WideErrorString[25]; CText TheText; +//--MIAMI: DONE CText::CText(void) { encoding = 'e'; + bHasMissionTextOffsets = false; + bIsMissionTextLoaded = false; + memset(szMissionTableName, 0, sizeof(szMissionTableName)); memset(WideErrorString, 0, sizeof(WideErrorString)); } +//--MIAMI: DONE void CText::Load(void) { - uint8 *filedata; - char filename[32], type[4]; - int length; - int offset, sectlen; + char filename[32]; + uint32 offset; + int file; + bool tkey_loaded = false, tdat_loaded = false; + ChunkHeader m_ChunkHeader; + + bIsMissionTextLoaded = false; + bHasMissionTextOffsets = false; Unload(); - filedata = new uint8[0x40000]; CFileMgr::SetDir("TEXT"); - switch(CMenuManager::m_PrefsLanguage){ + switch(FrontEndMenuManager.m_PrefsLanguage){ case LANGUAGE_AMERICAN: sprintf(filename, "AMERICAN.GXT"); break; @@ -59,45 +68,64 @@ CText::Load(void) #endif } - length = CFileMgr::LoadFile(filename, filedata, 0x40000, "rb"); - CFileMgr::SetDir(""); + file = CFileMgr::OpenFile(filename, "rb"); offset = 0; - while(offset < length){ - type[0] = filedata[offset++]; - type[1] = filedata[offset++]; - type[2] = filedata[offset++]; - type[3] = filedata[offset++]; - sectlen = (int)filedata[offset+3]<<24 | (int)filedata[offset+2]<<16 | - (int)filedata[offset+1]<<8 | (int)filedata[offset+0]; - offset += 4; - if(sectlen != 0){ - if(strncmp(type, "TKEY", 4) == 0) - keyArray.Load(sectlen, filedata, &offset); - else if(strncmp(type, "TDAT", 4) == 0) - data.Load(sectlen, filedata, &offset); - else - offset += sectlen; + while (!tkey_loaded || !tdat_loaded) { + ReadChunkHeader(&m_ChunkHeader, file, &offset); + if (m_ChunkHeader.size != 0) { + if (strncmp(m_ChunkHeader.magic, "TABL", 4) == 0) { + MissionTextOffsets.Load(m_ChunkHeader.size, file, &offset, 0x58000); + bHasMissionTextOffsets = true; + } else if (strncmp(m_ChunkHeader.magic, "TKEY", 4) == 0) { + this->keyArray.Load(m_ChunkHeader.size, file, &offset); + tkey_loaded = true; + } else if (strncmp(m_ChunkHeader.magic, "TDAT", 4) == 0) { + this->data.Load(m_ChunkHeader.size, file, &offset); + tdat_loaded = true; + } else { + CFileMgr::Seek(file, m_ChunkHeader.size, SEEK_CUR); + offset += m_ChunkHeader.size; + } } } keyArray.Update(data.chars); - - delete[] filedata; + CFileMgr::CloseFile(file); + CFileMgr::SetDir(""); } +//--MIAMI: DONE void CText::Unload(void) { CMessages::ClearAllMessagesDisplayedByGame(); - data.Unload(); keyArray.Unload(); + data.Unload(); + mission_keyArray.Unload(); + mission_data.Unload(); + bIsMissionTextLoaded = false; + memset(szMissionTableName, 0, sizeof(szMissionTableName)); } +//--MIAMI: DONE wchar* CText::Get(const char *key) { - return keyArray.Search(key); + uint8 result = false; +#ifdef FIX_BUGS + wchar *outstr = keyArray.Search(key, data.chars, &result); +#else + wchar *outstr = keyArray.Search(key, &result); +#endif + + if (!result && bHasMissionTextOffsets && bIsMissionTextLoaded) +#ifdef FIX_BUGS + outstr = mission_keyArray.Search(key, mission_data.chars, &result); +#else + outstr = mission_keyArray.Search(key, &result); +#endif + return outstr; } wchar UpperCaseTable[128] = { @@ -130,6 +158,7 @@ wchar FrenchUpperCaseTable[128] = { 253, 254, 255 }; +//--MIAMI: TODO (check tables) wchar CText::GetUpperCase(wchar c) { @@ -161,6 +190,7 @@ CText::GetUpperCase(wchar c) return c; } +//--MIAMI: DONE void CText::UpperCase(wchar *s) { @@ -170,21 +200,131 @@ CText::UpperCase(wchar *s) } } - +//--MIAMI: DONE void -CKeyArray::Load(uint32 length, uint8 *data, int *offset) +CText::GetNameOfLoadedMissionText(char *outName) { - uint32 i; - uint8 *rawbytes; + strcpy(outName, szMissionTableName); +} + +//--MIAMI: DONE +void +CText::ReadChunkHeader(ChunkHeader *buf, int32 file, uint32 *offset) +{ + // original code loops 8 times to read 1 byte with CFileMgr::Read, that's retarded + CFileMgr::Read(file, (char*)buf, sizeof(ChunkHeader)); + *offset += sizeof(ChunkHeader); +} + +//--MIAMI: DONE +void +CText::LoadMissionText(char *MissionTableName) +{ + char filename[32]; + + mission_keyArray.Unload(); + mission_data.Unload(); + + bool search_result = false; + int missionTableId = 0; + + for (missionTableId = 0; missionTableId < MissionTextOffsets.size; missionTableId++) { + if (strncmp(MissionTextOffsets.data[missionTableId].szMissionName, MissionTableName, strlen(MissionTextOffsets.data[missionTableId].szMissionName)) == 0) { + search_result = true; + break; + } + } + + if (!search_result) { + printf("CText::LoadMissionText - couldn't find %s", MissionTableName); + return; + } + + CFileMgr::SetDir("TEXT"); + switch (FrontEndMenuManager.m_PrefsLanguage) { + case LANGUAGE_AMERICAN: + sprintf(filename, "AMERICAN.GXT"); + break; + case LANGUAGE_FRENCH: + sprintf(filename, "FRENCH.GXT"); + break; + case LANGUAGE_GERMAN: + sprintf(filename, "GERMAN.GXT"); + break; + case LANGUAGE_ITALIAN: + sprintf(filename, "ITALIAN.GXT"); + break; + case LANGUAGE_SPANISH: + sprintf(filename, "SPANISH.GXT"); + break; +#ifdef MORE_LANGUAGES + case LANGUAGE_POLISH: + sprintf(filename, "POLISH.GXT"); + break; + case LANGUAGE_RUSSIAN: + sprintf(filename, "RUSSIAN.GXT"); + break; + case LANGUAGE_JAPANESE: + sprintf(filename, "JAPANESE.GXT"); + break; +#endif + } + CTimer::Suspend(); + int file = CFileMgr::OpenFile(filename, "rb"); + CFileMgr::Seek(file, MissionTextOffsets.data[missionTableId].offset, SEEK_SET); + + char TableCheck[8]; + CFileMgr::Read(file, TableCheck, 8); + if (strncmp(TableCheck, MissionTableName, 8) != 0) + printf("CText::LoadMissionText - expected to find %s in the text file", MissionTableName); + + bool tkey_loaded = false, tdat_loaded = false; + ChunkHeader m_ChunkHeader; + while (!tkey_loaded || !tdat_loaded) { + uint32 bytes_read = 0; + ReadChunkHeader(&m_ChunkHeader, file, &bytes_read); + if (m_ChunkHeader.size != 0) { + if (strncmp(m_ChunkHeader.magic, "TKEY", 4) == 0) { + uint32 bytes_read = 0; + mission_keyArray.Load(m_ChunkHeader.size, file, &bytes_read); + tkey_loaded = true; + } else if (strncmp(m_ChunkHeader.magic, "TDAT", 4) == 0) { + uint32 bytes_read = 0; + mission_data.Load(m_ChunkHeader.size, file, &bytes_read); + tdat_loaded = true; + } else + CFileMgr::Seek(file, m_ChunkHeader.size, SEEK_CUR); + } + } + + mission_keyArray.Update(mission_data.chars); + CFileMgr::CloseFile(file); + CTimer::Resume(); + CFileMgr::SetDir(""); + strcpy(szMissionTableName, MissionTableName); + bIsMissionTextLoaded = true; +} + + +//--MIAMI: DONE +void +CKeyArray::Load(uint32 length, int file, uint32 *offset) +{ + char *rawbytes; numEntries = length / sizeof(CKeyEntry); entries = new CKeyEntry[numEntries]; - rawbytes = (uint8*)entries; + rawbytes = (char*)entries; - for(i = 0; i < length; i++) - rawbytes[i] = data[(*offset)++]; +#if DUMB + for (uint32 i = 0; i < length; i++) + CFileMgr::Read(file, &rawbytes[i], 1); +#else + CFileMgr::Read(file, rawbytes, length); +#endif } +//--MIAMI: DONE void CKeyArray::Unload(void) { @@ -193,14 +333,18 @@ CKeyArray::Unload(void) numEntries = 0; } +//--MIAMI: DONE void CKeyArray::Update(wchar *chars) { +#ifndef FIX_BUGS int i; for(i = 0; i < numEntries; i++) entries[i].value = (wchar*)((uint8*)chars + (uintptr)entries[i].value); +#endif } +//--MIAMI: DONE CKeyEntry* CKeyArray::BinarySearch(const char *key, CKeyEntry *entries, int16 low, int16 high) { @@ -221,37 +365,61 @@ CKeyArray::BinarySearch(const char *key, CKeyEntry *entries, int16 low, int16 hi return nil; } +//--MIAMI: DONE wchar* -CKeyArray::Search(const char *key) +#ifdef FIX_BUGS +CKeyArray::Search(const char *key, wchar *data, uint8 *result) +#else +CKeyArray::Search(const char *key, uint8 *result) +#endif { CKeyEntry *found; char errstr[25]; int i; +#ifdef FIX_BUGS found = BinarySearch(key, entries, 0, numEntries-1); - if(found) + if (found) { + *result = true; + return (wchar*)((uint8*)data + found->valueOffset); + } +#else + found = BinarySearch(key, entries, 0, numEntries-1); + if (found) { + *result = true; return found->value; + } +#endif + *result = false; +#ifdef MASTER + sprintf(errstr, "%"); +#else sprintf(errstr, "%s missing", key); +#endif // MASTER for(i = 0; i < 25; i++) WideErrorString[i] = errstr[i]; return WideErrorString; } - +//--MIAMI: DONE void -CData::Load(uint32 length, uint8 *data, int *offset) +CData::Load(uint32 length, int file, uint32 *offset) { - uint32 i; - uint8 *rawbytes; + char *rawbytes; numChars = length / sizeof(wchar); chars = new wchar[numChars]; - rawbytes = (uint8*)chars; + rawbytes = (char*)chars; - for(i = 0; i < length; i++) - rawbytes[i] = data[(*offset)++]; +#if DUMB + for(uint32 i = 0; i < length; i++) + CFileMgr::Read(file, &rawbytes[i], 1); +#else + CFileMgr::Read(file, rawbytes, length); +#endif } +//--MIAMI: DONE void CData::Unload(void) { @@ -260,6 +428,16 @@ CData::Unload(void) numChars = 0; } +//--MIAMI: DONE +void +CMissionTextOffsets::Load(uint32 table_size, int file, uint32 *offset, int) +{ + // not exact VC code but smaller and better :P + size = table_size / sizeof(CMissionTextOffsets::Entry); + CFileMgr::Read(file, (char*)data, sizeof(CMissionTextOffsets::Entry) * size); + *offset += sizeof(CMissionTextOffsets::Entry) * size; +} + void AsciiToUnicode(const char *src, wchar *dst) { diff --git a/src/text/Text.h b/src/text/Text.h index 4255e2a5..dcffccbf 100644 --- a/src/text/Text.h +++ b/src/text/Text.h @@ -9,7 +9,11 @@ void TextCopy(wchar *dst, const wchar *src); struct CKeyEntry { +#ifdef FIX_BUGS + uint32 valueOffset; +#else wchar *value; +#endif char key[8]; }; @@ -24,11 +28,15 @@ public: CKeyArray(void) : entries(nil), numEntries(0) {} ~CKeyArray(void) { Unload(); } - void Load(uint32 length, uint8 *data, int *offset); + void Load(uint32 length, int file, uint32 *offset); void Unload(void); void Update(wchar *chars); CKeyEntry *BinarySearch(const char *key, CKeyEntry *entries, int16 low, int16 high); - wchar *Search(const char *key); +#ifdef FIX_BUGS + wchar *Search(const char *key, wchar *data, uint8 *result); +#else + wchar *Search(const char *key, uint8* result); +#endif }; class CData @@ -39,15 +47,45 @@ public: CData(void) : chars(nil), numChars(0) {} ~CData(void) { Unload(); } - void Load(uint32 length, uint8 *data, int *offset); + void Load(uint32 length, int file, uint32 *offset); void Unload(void); }; +class CMissionTextOffsets +{ +public: + struct Entry + { + char szMissionName[8]; + uint32 offset; + }; + + enum {MAX_MISSION_TEXTS = 90}; // beware that LCS has more + + Entry data[MAX_MISSION_TEXTS]; + uint16 size; + + CMissionTextOffsets(void) : size(0) {} + void Load(uint32 table_size, int file, uint32* bytes_read, int); +}; + +struct ChunkHeader +{ + char magic[4]; + int size; +}; + class CText { CKeyArray keyArray; CData data; + CKeyArray mission_keyArray; + CData mission_data; char encoding; + bool bHasMissionTextOffsets; + bool bIsMissionTextLoaded; + char szMissionTableName[8]; + CMissionTextOffsets MissionTextOffsets; public: CText(void); void Load(void); @@ -55,6 +93,9 @@ public: wchar *Get(const char *key); wchar GetUpperCase(wchar c); void UpperCase(wchar *s); + void GetNameOfLoadedMissionText(char *outName); + void ReadChunkHeader(ChunkHeader *buf, int32 file, uint32 *bytes_read); + void LoadMissionText(char *MissionTableName); }; extern CText TheText; diff --git a/src/vehicles/Automobile.cpp b/src/vehicles/Automobile.cpp index 6e88b997..fbcf610c 100644 --- a/src/vehicles/Automobile.cpp +++ b/src/vehicles/Automobile.cpp @@ -72,10 +72,12 @@ CAutomobile::CAutomobile(int32 id, uint8 CreatedBy) bFixedColour = false; bBigWheels = false; bWaterTight = false; + bTankDetonateCars = true; SetModelIndex(id); pHandling = mod_HandlingManager.GetHandlingData((eHandlingId)mi->m_handlingId); + pFlyingHandling = mod_HandlingManager.GetFlyingPointer((eHandlingId)mi->m_handlingId); field_49C = 20.0f; field_4D8 = 0; @@ -175,7 +177,7 @@ CAutomobile::CAutomobile(int32 id, uint8 CreatedBy) m_nNumPassengers = 0; m_bombType = CARBOMB_NONE; - bHadDriver = false; + bDriverLastFrame = false; m_pBombRigger = nil; if(m_nDoorLock == CARLOCK_UNLOCKED && @@ -271,25 +273,14 @@ CAutomobile::ProcessControl(void) } // Process driver - if(pDriver){ - if(!bHadDriver && m_bombType == CARBOMB_ONIGNITIONACTIVE){ - // If someone enters the car and there is a bomb, detonate - m_nBombTimer = 1000; - m_pBlowUpEntity = m_pBombRigger; - if(m_pBlowUpEntity) - m_pBlowUpEntity->RegisterReference((CEntity**)&m_pBlowUpEntity); - DMAudio.PlayOneShot(m_audioEntityId, SOUND_BOMB_TICK, 1.0f); - } - bHadDriver = true; + if(IsUpsideDown() && CanPedEnterCar()){ + if(!pDriver->IsPlayer() && + !(pDriver->m_leader && pDriver->m_leader->bInVehicle) && + pDriver->CharCreatedBy != MISSION_CHAR) + pDriver->SetObjective(OBJECTIVE_LEAVE_VEHICLE, this); + } - if(IsUpsideDown() && CanPedEnterCar()){ - if(!pDriver->IsPlayer() && - !(pDriver->m_leader && pDriver->m_leader->bInVehicle) && - pDriver->CharCreatedBy != MISSION_CHAR) - pDriver->SetObjective(OBJECTIVE_LEAVE_VEHICLE, this); - } - }else - bHadDriver = false; + ActivateBombWhenEntered(); // Process passengers if(m_nNumPassengers != 0 && IsUpsideDown() && CanPedEnterCar()){ @@ -303,18 +294,7 @@ CAutomobile::ProcessControl(void) CRubbish::StirUp(this); - // blend in clump - int clumpAlpha = CVisibilityPlugins::GetClumpAlpha((RpClump*)m_rwObject); - if(bFadeOut){ - clumpAlpha -= 8; - if(clumpAlpha < 0) - clumpAlpha = 0; - }else if(clumpAlpha < 255){ - clumpAlpha += 16; - if(clumpAlpha > 255) - clumpAlpha = 255; - } - CVisibilityPlugins::SetClumpAlpha((RpClump*)m_rwObject, clumpAlpha); + UpdateClumpAlpha(); AutoPilot.m_bSlowedDownBecauseOfCars = false; AutoPilot.m_bSlowedDownBecauseOfPeds = false; @@ -332,7 +312,7 @@ CAutomobile::ProcessControl(void) bool playerRemote = false; switch(GetStatus()){ case STATUS_PLAYER_REMOTE: - if(CPad::GetPad(0)->WeaponJustDown()){ + if(CPad::GetPad(0)->WeaponJustDown() && !bDisableRemoteDetonation){ BlowUpCar(FindPlayerPed()); CRemote::TakeRemoteControlledCarFromPlayer(); } @@ -629,7 +609,7 @@ CAutomobile::ProcessControl(void) m_aSuspensionSpringRatio[i], bias); m_aWheelSkidmarkMuddy[i] = m_aWheelColPoints[i].surfaceB == SURFACE_GRASS || - m_aWheelColPoints[i].surfaceB == SURFACE_DIRTTRACK || + m_aWheelColPoints[i].surfaceB == SURFACE_MUD_DRY || m_aWheelColPoints[i].surfaceB == SURFACE_SAND; }else{ contactPoints[i] = Multiply3x3(GetMatrix(), colModel->lines[i].p1); @@ -725,19 +705,8 @@ CAutomobile::ProcessControl(void) traction *= 4.0f; if(FindPlayerVehicle() && FindPlayerVehicle() == this){ - if(CPad::GetPad(0)->WeaponJustDown()){ - if(m_bombType == CARBOMB_TIMED){ - m_bombType = CARBOMB_TIMEDACTIVE; - m_nBombTimer = 7000; - m_pBlowUpEntity = FindPlayerPed(); - CGarages::TriggerMessage("GA_12", -1, 3000, -1); - DMAudio.PlayOneShot(m_audioEntityId, SOUND_BOMB_TIMED_ACTIVATED, 1.0f); - }else if(m_bombType == CARBOMB_ONIGNITION){ - m_bombType = CARBOMB_ONIGNITIONACTIVE; - CGarages::TriggerMessage("GA_12", -1, 3000, -1); - DMAudio.PlayOneShot(m_audioEntityId, SOUND_BOMB_ONIGNITION_ACTIVATED, 1.0f); - } - } + if(CPad::GetPad(0)->WeaponJustDown()) + ActivateBomb(); }else if(strongGrip1 || CVehicle::bCheat3){ traction *= 1.2f; acceleration *= 1.4f; @@ -764,7 +733,7 @@ CAutomobile::ProcessControl(void) else fThrust = acceleration; - m_aWheelColPoints[CARWHEEL_FRONT_LEFT].surfaceA = SURFACE_RUBBER29; + m_aWheelColPoints[CARWHEEL_FRONT_LEFT].surfaceA = SURFACE_WHEELBASE; float adhesion = CSurfaceTable::GetAdhesiveLimit(m_aWheelColPoints[CARWHEEL_FRONT_LEFT])*traction; if(GetStatus() == STATUS_PLAYER) adhesion *= CSurfaceTable::GetWetMultiplier(m_aWheelColPoints[CARWHEEL_FRONT_LEFT].surfaceB); @@ -798,7 +767,7 @@ CAutomobile::ProcessControl(void) else fThrust = acceleration; - m_aWheelColPoints[CARWHEEL_FRONT_RIGHT].surfaceA = SURFACE_RUBBER29; + m_aWheelColPoints[CARWHEEL_FRONT_RIGHT].surfaceA = SURFACE_WHEELBASE; float adhesion = CSurfaceTable::GetAdhesiveLimit(m_aWheelColPoints[CARWHEEL_FRONT_RIGHT])*traction; if(GetStatus() == STATUS_PLAYER) adhesion *= CSurfaceTable::GetWetMultiplier(m_aWheelColPoints[CARWHEEL_FRONT_RIGHT].surfaceB); @@ -864,8 +833,14 @@ CAutomobile::ProcessControl(void) CVector wheelFwd = GetForward(); CVector wheelRight = GetRight(); +#ifdef FIX_BUGS + // Not sure if this is needed, but brake usually has timestep as a factor + if(bIsHandbrakeOn) + brake = 20000.0f * CTimer::GetTimeStepFix(); +#else if(bIsHandbrakeOn) brake = 20000.0f; +#endif if(m_aWheelTimer[CARWHEEL_REAR_LEFT] > 0.0f){ if(mod_HandlingManager.HasFrontWheelDrive(pHandling->nIdentifier)) @@ -873,7 +848,7 @@ CAutomobile::ProcessControl(void) else fThrust = acceleration; - m_aWheelColPoints[CARWHEEL_REAR_LEFT].surfaceA = SURFACE_RUBBER29; + m_aWheelColPoints[CARWHEEL_REAR_LEFT].surfaceA = SURFACE_WHEELBASE; float adhesion = CSurfaceTable::GetAdhesiveLimit(m_aWheelColPoints[CARWHEEL_REAR_LEFT])*traction; if(GetStatus() == STATUS_PLAYER) adhesion *= CSurfaceTable::GetWetMultiplier(m_aWheelColPoints[CARWHEEL_REAR_LEFT].surfaceB); @@ -907,7 +882,7 @@ CAutomobile::ProcessControl(void) else fThrust = acceleration; - m_aWheelColPoints[CARWHEEL_REAR_RIGHT].surfaceA = SURFACE_RUBBER29; + m_aWheelColPoints[CARWHEEL_REAR_RIGHT].surfaceA = SURFACE_WHEELBASE; float adhesion = CSurfaceTable::GetAdhesiveLimit(m_aWheelColPoints[CARWHEEL_REAR_RIGHT])*traction; if(GetStatus() == STATUS_PLAYER) adhesion *= CSurfaceTable::GetWetMultiplier(m_aWheelColPoints[CARWHEEL_REAR_RIGHT].surfaceB); @@ -1122,10 +1097,10 @@ CAutomobile::ProcessControl(void) } uint8 surf = m_aWheelColPoints[i].surfaceB; - if(surf == SURFACE_DIRT || surf == SURFACE_PUDDLE || surf == SURFACE_HEDGE){ + if(surf == SURFACE_GRAVEL || surf == SURFACE_WATER || surf == SURFACE_HEDGE){ if(surfShake < 0.2f) surfShake = 0.3f; - }else if(surf == SURFACE_DIRTTRACK || surf == SURFACE_SAND){ + }else if(surf == SURFACE_MUD_DRY || surf == SURFACE_SAND){ if(surfShake < 0.1f) surfShake = 0.2f; }else if(surf == SURFACE_GRASS){ @@ -1927,6 +1902,8 @@ CAutomobile::PreRender(void) } CShadows::StoreShadowForCar(this); + + DoSunGlare(); } void @@ -2185,6 +2162,7 @@ CAutomobile::ProcessEntityCollision(CEntity *ent, CColPoint *colpoints) phys->RegisterReference((CEntity**)&m_aGroundPhysical[i]); m_aGroundOffset[i] = m_aWheelColPoints[i].point - phys->GetPosition(); +#if 0 if(phys->GetModelIndex() == MI_BODYCAST && GetStatus() == STATUS_PLAYER){ // damage body cast float speed = m_vecMoveSpeed.MagnitudeSqr(); @@ -2201,6 +2179,7 @@ CAutomobile::ProcessEntityCollision(CEntity *ent, CColPoint *colpoints) phys->AddToMovingList(); } } +#endif } m_nSurfaceTouched = m_aWheelColPoints[i].surfaceB; @@ -2846,6 +2825,7 @@ CAutomobile::ProcessBuoyancy(void) if(impulseRatio > 0.5f){ bIsInWater = true; + bIsDrowning = true; if(m_vecMoveSpeed.z < -0.1f) m_vecMoveSpeed.z = -0.1f; @@ -2860,8 +2840,11 @@ CAutomobile::ProcessBuoyancy(void) if(pPassengers[i]->IsPlayer() || !bWaterTight) pPassengers[i]->InflictDamage(nil, WEAPONTYPE_DROWNING, CTimer::GetTimeStep(), PEDPIECE_TORSO, 0); } - }else + } + else { bIsInWater = false; + bIsDrowning = false; + } static uint32 nGenerateRaindrops = 0; static uint32 nGenerateWaterCircles = 0; @@ -2943,13 +2926,14 @@ CAutomobile::ProcessBuoyancy(void) } }else{ bIsInWater = false; + bIsDrowning = false; bTouchingWater = false; static RwRGBA splashCol = {155, 155, 185, 196}; static RwRGBA smokeCol = {255, 255, 255, 255}; for(i = 0; i < 4; i++){ - if(m_aSuspensionSpringRatio[i] < 1.0f && m_aWheelColPoints[i].surfaceB == SURFACE_PUDDLE){ + if(m_aSuspensionSpringRatio[i] < 1.0f && m_aWheelColPoints[i].surfaceB == SURFACE_WATER){ CVector pos = m_aWheelColPoints[i].point + 0.3f*GetUp() - GetPosition(); CVector vSpeed = GetSpeed(pos); vSpeed.z = 0.0f; @@ -3016,12 +3000,16 @@ CAutomobile::ProcessBuoyancy(void) void CAutomobile::DoDriveByShootings(void) { - CAnimBlendAssociation *anim; + CAnimBlendAssociation *anim = nil; + CPlayerInfo* playerInfo = ((CPlayerPed*)this)->GetPlayerInfoForThisPlayerPed(); + if (playerInfo && !playerInfo->m_bDriveByAllowed) + return; + CWeapon *weapon = pDriver->GetWeapon(); if(CWeaponInfo::GetWeaponInfo(weapon->m_eWeaponType)->m_nWeaponSlot != 5) return; - weapon->Update(pDriver->m_audioEntityId); + weapon->Update(pDriver->m_audioEntityId, nil); bool lookingLeft = false; bool lookingRight = false; @@ -3037,37 +3025,42 @@ CAutomobile::DoDriveByShootings(void) lookingRight = true; } + AnimationId rightAnim = ANIM_DRIVEBY_R; + AnimationId leftAnim = ANIM_DRIVEBY_L; + if (pDriver->m_pMyVehicle->bLowVehicle) { + rightAnim = ANIM_DRIVEBY_LOW_R; + leftAnim = ANIM_DRIVEBY_LOW_L; + } + if(lookingLeft || lookingRight){ if(lookingLeft){ - anim = RpAnimBlendClumpGetAssociation(pDriver->GetClump(), ANIM_DRIVEBY_R); + anim = RpAnimBlendClumpGetAssociation(pDriver->GetClump(), rightAnim); if(anim) anim->blendDelta = -1000.0f; - anim = RpAnimBlendClumpGetAssociation(pDriver->GetClump(), ANIM_DRIVEBY_L); + anim = RpAnimBlendClumpGetAssociation(pDriver->GetClump(), leftAnim); if(anim == nil || anim->blendDelta < 0.0f) - CAnimManager::AddAnimation(pDriver->GetClump(), ASSOCGRP_STD, ANIM_DRIVEBY_L); - else - anim->SetRun(); + anim = CAnimManager::AddAnimation(pDriver->GetClump(), ASSOCGRP_STD, leftAnim); }else if(pDriver->m_pMyVehicle->pPassengers[0] == nil || TheCamera.Cams[TheCamera.ActiveCam].Mode == CCam::MODE_1STPERSON){ - anim = RpAnimBlendClumpGetAssociation(pDriver->GetClump(), ANIM_DRIVEBY_L); + anim = RpAnimBlendClumpGetAssociation(pDriver->GetClump(), leftAnim); if(anim) anim->blendDelta = -1000.0f; - anim = RpAnimBlendClumpGetAssociation(pDriver->GetClump(), ANIM_DRIVEBY_R); + anim = RpAnimBlendClumpGetAssociation(pDriver->GetClump(), rightAnim); if(anim == nil || anim->blendDelta < 0.0f) - CAnimManager::AddAnimation(pDriver->GetClump(), ASSOCGRP_STD, ANIM_DRIVEBY_R); - else - anim->SetRun(); + anim = CAnimManager::AddAnimation(pDriver->GetClump(), ASSOCGRP_STD, rightAnim); } - if(CPad::GetPad(0)->GetCarGunFired() && CTimer::GetTimeInMilliseconds() > weapon->m_nTimer){ - weapon->FireFromCar(this, lookingLeft); - weapon->m_nTimer = CTimer::GetTimeInMilliseconds() + 70; + if (!anim || !anim->IsRunning()) { + if (CPad::GetPad(0)->GetCarGunFired() && CTimer::GetTimeInMilliseconds() > weapon->m_nTimer) { + weapon->FireFromCar(this, lookingLeft); + weapon->m_nTimer = CTimer::GetTimeInMilliseconds() + 70; + } } }else{ weapon->Reload(); - anim = RpAnimBlendClumpGetAssociation(pDriver->GetClump(), ANIM_DRIVEBY_L); + anim = RpAnimBlendClumpGetAssociation(pDriver->GetClump(), leftAnim); if(anim) anim->blendDelta = -1000.0f; - anim = RpAnimBlendClumpGetAssociation(pDriver->GetClump(), ANIM_DRIVEBY_R); + anim = RpAnimBlendClumpGetAssociation(pDriver->GetClump(), rightAnim); if(anim) anim->blendDelta = -1000.0f; } @@ -3075,11 +3068,11 @@ CAutomobile::DoDriveByShootings(void) // TODO: what is this? if(!lookingLeft && m_weaponDoorTimerLeft > 0.0f){ m_weaponDoorTimerLeft = Max(m_weaponDoorTimerLeft - CTimer::GetTimeStep()*0.1f, 0.0f); - ProcessOpenDoor(CAR_DOOR_LF, NUM_ANIMS, m_weaponDoorTimerLeft); + ProcessOpenDoor(CAR_DOOR_LF, NUM_STD_ANIMS, m_weaponDoorTimerLeft); } if(!lookingRight && m_weaponDoorTimerRight > 0.0f){ m_weaponDoorTimerRight = Max(m_weaponDoorTimerRight - CTimer::GetTimeStep()*0.1f, 0.0f); - ProcessOpenDoor(CAR_DOOR_RF, NUM_ANIMS, m_weaponDoorTimerRight); + ProcessOpenDoor(CAR_DOOR_RF, NUM_STD_ANIMS, m_weaponDoorTimerRight); } } @@ -3547,7 +3540,7 @@ CAutomobile::AddWheelDirtAndWater(CColPoint *colpoint, uint32 belowEffectSpeed) CGeneral::GetRandomNumberInRange(0.02f, 0.1f), grassCol); } return 0; - case SURFACE_DIRT: + case SURFACE_GRAVEL: dir.x = -0.05f*m_vecMoveSpeed.x; dir.y = -0.05f*m_vecMoveSpeed.y; for(i = 0; i < 4; i++){ @@ -3556,7 +3549,7 @@ CAutomobile::AddWheelDirtAndWater(CColPoint *colpoint, uint32 belowEffectSpeed) CGeneral::GetRandomNumberInRange(0.02f, 0.06f), dirtCol); } return 1; - case SURFACE_DIRTTRACK: + case SURFACE_MUD_DRY: dir.x = -0.05f*m_vecMoveSpeed.x; dir.y = -0.05f*m_vecMoveSpeed.y; for(i = 0; i < 4; i++){ @@ -3764,7 +3757,7 @@ CAutomobile::ProcessOpenDoor(uint32 component, uint32 anim, float time) case ANIM_VAN_GETOUT: ProcessDoorOpenAnimation(this, component, door, time, 0.5f, 0.6f); break; - case NUM_ANIMS: + case NUM_STD_ANIMS: OpenDoor(component, door, time); break; } @@ -3906,19 +3899,19 @@ CAutomobile::SetUpWheelColModel(CColModel *colModel) CMatrix mat; mat.Attach(RwFrameGetMatrix(m_aCarNodes[CAR_WHEEL_LF])); - colModel->spheres[0].Set(mi->m_wheelScale, mat.GetPosition(), SURFACE_TIRE, CAR_PIECE_WHEEL_LF); + colModel->spheres[0].Set(mi->m_wheelScale, mat.GetPosition(), SURFACE_RUBBER, CAR_PIECE_WHEEL_LF); mat.Attach(RwFrameGetMatrix(m_aCarNodes[CAR_WHEEL_LB])); - colModel->spheres[1].Set(mi->m_wheelScale, mat.GetPosition(), SURFACE_TIRE, CAR_PIECE_WHEEL_LR); + colModel->spheres[1].Set(mi->m_wheelScale, mat.GetPosition(), SURFACE_RUBBER, CAR_PIECE_WHEEL_LR); mat.Attach(RwFrameGetMatrix(m_aCarNodes[CAR_WHEEL_RF])); - colModel->spheres[2].Set(mi->m_wheelScale, mat.GetPosition(), SURFACE_TIRE, CAR_PIECE_WHEEL_RF); + colModel->spheres[2].Set(mi->m_wheelScale, mat.GetPosition(), SURFACE_RUBBER, CAR_PIECE_WHEEL_RF); mat.Attach(RwFrameGetMatrix(m_aCarNodes[CAR_WHEEL_RB])); - colModel->spheres[3].Set(mi->m_wheelScale, mat.GetPosition(), SURFACE_TIRE, CAR_PIECE_WHEEL_RR); + colModel->spheres[3].Set(mi->m_wheelScale, mat.GetPosition(), SURFACE_RUBBER, CAR_PIECE_WHEEL_RR); if(m_aCarNodes[CAR_WHEEL_LM] != nil && m_aCarNodes[CAR_WHEEL_RM] != nil){ mat.Attach(RwFrameGetMatrix(m_aCarNodes[CAR_WHEEL_LM])); - colModel->spheres[4].Set(mi->m_wheelScale, mat.GetPosition(), SURFACE_TIRE, CAR_PIECE_WHEEL_RF); + colModel->spheres[4].Set(mi->m_wheelScale, mat.GetPosition(), SURFACE_RUBBER, CAR_PIECE_WHEEL_LR); mat.Attach(RwFrameGetMatrix(m_aCarNodes[CAR_WHEEL_RM])); - colModel->spheres[5].Set(mi->m_wheelScale, mat.GetPosition(), SURFACE_TIRE, CAR_PIECE_WHEEL_RR); + colModel->spheres[5].Set(mi->m_wheelScale, mat.GetPosition(), SURFACE_RUBBER, CAR_PIECE_WHEEL_RR); colModel->numSpheres = 6; }else colModel->numSpheres = 4; @@ -3926,9 +3919,8 @@ CAutomobile::SetUpWheelColModel(CColModel *colModel) return true; } -// this probably isn't used in III yet void -CAutomobile::BurstTyre(uint8 wheel) +CAutomobile::BurstTyre(uint8 wheel, bool applyForces) { switch(wheel){ case CAR_PIECE_WHEEL_LF: wheel = VEHWHEEL_FRONT_LEFT; break; @@ -3946,8 +3938,10 @@ CAutomobile::BurstTyre(uint8 wheel) CCarCtrl::SwitchVehicleToRealPhysics(this); } - ApplyMoveForce(GetRight() * CGeneral::GetRandomNumberInRange(-0.3f, 0.3f)); - ApplyTurnForce(GetRight() * CGeneral::GetRandomNumberInRange(-0.3f, 0.3f), GetForward()); + if(applyForces){ + ApplyMoveForce(GetRight() * CGeneral::GetRandomNumberInRange(-0.3f, 0.3f)); + ApplyTurnForce(GetRight() * CGeneral::GetRandomNumberInRange(-0.3f, 0.3f), GetForward()); + } } } @@ -4024,10 +4018,22 @@ CAutomobile::PlayCarHorn(void) { int r; + if (m_nAlarmState && m_nAlarmState != -1) + return; + + if (GetStatus() == STATUS_WRECKED) + return; + if(m_nCarHornTimer != 0) return; - r = CGeneral::GetRandomNumber() & 7; + if (m_nCarHornDelay) { + m_nCarHornDelay--; + return; + } + + m_nCarHornDelay = (CGeneral::GetRandomNumber() & 0x7F) + 150; + r = m_nCarHornDelay & 7; if(r < 2){ m_nCarHornTimer = 45; }else if(r < 4){ @@ -4127,7 +4133,7 @@ CAutomobile::BlowUpCarsInPath(void) { int i; - if(m_vecMoveSpeed.Magnitude() > 0.1f) + if(m_vecMoveSpeed.Magnitude() > 0.1f && bTankDetonateCars) for(i = 0; i < m_nCollisionRecords; i++) if(m_aCollisionRecords[i] && m_aCollisionRecords[i]->IsVehicle() && @@ -4302,7 +4308,7 @@ GetCurrentAtomicObjectCB(RwObject *object, void *data) return object; } -CColPoint spherepoints[MAX_COLLISION_POINTS]; +static CColPoint aTempPedColPts[MAX_COLLISION_POINTS]; CObject* CAutomobile::SpawnFlyingComponent(int32 component, uint32 type) @@ -4422,7 +4428,7 @@ CAutomobile::SpawnFlyingComponent(int32 component, uint32 type) if(CCollision::ProcessColModels(obj->GetMatrix(), *obj->GetColModel(), this->GetMatrix(), *this->GetColModel(), - spherepoints, nil, nil) > 0) + aTempPedColPts, nil, nil) > 0) obj->m_pCollidingEntity = this; if(bRenderScorched) @@ -4589,6 +4595,18 @@ CAutomobile::SetAllTaxiLights(bool set) m_sAllTaxiLights = set; } +void +CAutomobile::TellHeliToGoToCoors(float x, float y, float z, uint8 speed) +{ + AutoPilot.m_nCarMission = MISSION_HELI_FLYTOCOORS; + AutoPilot.m_vecDestinationCoors.x = x; + AutoPilot.m_vecDestinationCoors.y = y; + AutoPilot.m_vecDestinationCoors.z = z; + AutoPilot.m_nCruiseSpeed = speed; + SetStatus(STATUS_PHYSICS); + //TODO(MIAMI) +} + #ifdef COMPATIBLE_SAVES void CAutomobile::Save(uint8*& buf) diff --git a/src/vehicles/Automobile.h b/src/vehicles/Automobile.h index 8c5c8f8e..883177aa 100644 --- a/src/vehicles/Automobile.h +++ b/src/vehicles/Automobile.h @@ -83,14 +83,16 @@ public: float m_aWheelRotation[4]; float m_aWheelPosition[4]; float m_aWheelSpeed[4]; + float m_fRotorSpeed; uint8 field_4D8; uint8 bTaxiLight : 1; - uint8 bHadDriver : 1; // for bombs + //uint8 bHadDriver : 1; // for bombs uint8 bFixedColour : 1; uint8 bBigWheels : 1; uint8 bWaterTight : 1; // no damage for non-player peds uint8 bNotDamagedUpsideDown : 1; uint8 bMoreResistantToDamage : 1; + uint8 bTankDetonateCars : 1; int16 field_4E0; uint16 m_hydraulicState; uint32 m_nBusDoorTimerEnd; @@ -145,7 +147,7 @@ public: void RemoveRefsToVehicle(CEntity *ent); void BlowUpCar(CEntity *ent); bool SetUpWheelColModel(CColModel *colModel); - void BurstTyre(uint8 tyre); + void BurstTyre(uint8 tyre, bool applyForces); bool IsRoomForPedToLeaveCar(uint32 component, CVector *doorOffset); float GetHeightAboveRoad(void); void PlayCarHorn(void); @@ -178,6 +180,8 @@ public: void SetBumperDamage(int32 component, ePanels panel, bool noFlyingComponents = false); void SetDoorDamage(int32 component, eDoors door, bool noFlyingComponents = false); + void TellHeliToGoToCoors(float x, float y, float z, uint8 speed); + void Fix(void); void SetComponentVisibility(RwFrame *frame, uint32 flags); void SetupModelNodes(void); diff --git a/src/vehicles/Boat.cpp b/src/vehicles/Boat.cpp index 784d859f..b9d97716 100644 --- a/src/vehicles/Boat.cpp +++ b/src/vehicles/Boat.cpp @@ -19,6 +19,9 @@ #include "Pools.h" #include "Pad.h" #include "Boat.h" +#include "AnimBlendAssociation.h" +#include "RpAnimBlend.h" +#include "Record.h" #define INVALID_ORIENTATION (-9999.99f) @@ -80,7 +83,7 @@ CBoat::CBoat(int mi, uint8 owner) : CVehicle(owner) bIsInWater = true; - unk1 = 0.0f; + m_phys_unused1 = 0.0f; m_bIsAnchored = true; m_fOrientation = INVALID_ORIENTATION; bTouchingWater = true; @@ -149,6 +152,9 @@ CBoat::ProcessControl(void) ProcessControlInputs(0); if(GetModelIndex() == MI_PREDATOR) DoFixedMachineGuns(); + + if (!CRecordDataForChase::IsRecording()) + DoDriveByShootings(); break; case STATUS_SIMPLE: m_bIsAnchored = false; @@ -267,9 +273,17 @@ CBoat::ProcessControl(void) if(0.1f * m_fMass * GRAVITY*CTimer::GetTimeStep() < buoyanceImpulse.z){ bBoatInWater = true; bIsInWater = true; + if (GetUp().z < -0.6f && Abs(GetMoveSpeed().x) < 0.05 && Abs(GetMoveSpeed().y) < 0.05) { + bIsDrowning = true; + if (pDriver) + pDriver->InflictDamage(nil, WEAPONTYPE_DROWNING, CTimer::GetTimeStep(), PEDPIECE_TORSO, 0); + } + else + bIsDrowning = false; }else{ bBoatInWater = false; bIsInWater = false; + bIsDrowning = false; } m_fVolumeUnderWater = mod_Buoyancy.m_volumeUnderWater; @@ -513,6 +527,7 @@ CBoat::ProcessControl(void) }else{ bBoatInWater = false; bIsInWater = false; + bIsDrowning = false; } if(m_bIsAnchored){ @@ -912,6 +927,68 @@ CBoat::AddWakePoint(CVector point) } } +void +CBoat::DoDriveByShootings(void) +{ + CAnimBlendAssociation *anim = nil; + CPlayerInfo* playerInfo = ((CPlayerPed*)this)->GetPlayerInfoForThisPlayerPed(); + if (playerInfo && !playerInfo->m_bDriveByAllowed) + return; + + CWeapon *weapon = pDriver->GetWeapon(); + if(CWeaponInfo::GetWeaponInfo(weapon->m_eWeaponType)->m_nWeaponSlot != 5) + return; + + weapon->Update(pDriver->m_audioEntityId, nil); + + bool lookingLeft = false; + bool lookingRight = false; + if(TheCamera.Cams[TheCamera.ActiveCam].Mode == CCam::MODE_TOPDOWN){ + if(CPad::GetPad(0)->GetLookLeft()) + lookingLeft = true; + if(CPad::GetPad(0)->GetLookRight()) + lookingRight = true; + }else{ + if(TheCamera.Cams[TheCamera.ActiveCam].LookingLeft) + lookingLeft = true; + if(TheCamera.Cams[TheCamera.ActiveCam].LookingRight) + lookingRight = true; + } + + if(lookingLeft || lookingRight){ + if(lookingLeft){ + anim = RpAnimBlendClumpGetAssociation(pDriver->GetClump(), ANIM_DRIVEBY_R); + if(anim) + anim->blendDelta = -1000.0f; + anim = RpAnimBlendClumpGetAssociation(pDriver->GetClump(), ANIM_DRIVEBY_L); + if(anim == nil || anim->blendDelta < 0.0f) + anim = CAnimManager::AddAnimation(pDriver->GetClump(), ASSOCGRP_STD, ANIM_DRIVEBY_L); + }else if(pDriver->m_pMyVehicle->pPassengers[0] == nil || TheCamera.Cams[TheCamera.ActiveCam].Mode == CCam::MODE_1STPERSON){ + anim = RpAnimBlendClumpGetAssociation(pDriver->GetClump(), ANIM_DRIVEBY_L); + if(anim) + anim->blendDelta = -1000.0f; + anim = RpAnimBlendClumpGetAssociation(pDriver->GetClump(), ANIM_DRIVEBY_R); + if(anim == nil || anim->blendDelta < 0.0f) + anim = CAnimManager::AddAnimation(pDriver->GetClump(), ASSOCGRP_STD, ANIM_DRIVEBY_R); + } + + if (!anim || !anim->IsRunning()) { + if (CPad::GetPad(0)->GetCarGunFired() && CTimer::GetTimeInMilliseconds() > weapon->m_nTimer) { + weapon->FireFromCar(this, lookingLeft); + weapon->m_nTimer = CTimer::GetTimeInMilliseconds() + 70; + } + } + }else{ + weapon->Reload(); + anim = RpAnimBlendClumpGetAssociation(pDriver->GetClump(), ANIM_DRIVEBY_L); + if(anim) + anim->blendDelta = -1000.0f; + anim = RpAnimBlendClumpGetAssociation(pDriver->GetClump(), ANIM_DRIVEBY_R); + if(anim) + anim->blendDelta = -1000.0f; + } +} + #ifdef COMPATIBLE_SAVES void CBoat::Save(uint8*& buf) diff --git a/src/vehicles/Boat.h b/src/vehicles/Boat.h index 7a0a9be4..c8168db0 100644 --- a/src/vehicles/Boat.h +++ b/src/vehicles/Boat.h @@ -61,6 +61,7 @@ public: void SetupModelNodes(); void PruneWakeTrail(void); void AddWakePoint(CVector point); + void DoDriveByShootings(void); static CBoat *apFrameWakeGeneratingBoats[4]; diff --git a/src/vehicles/CarGen.cpp b/src/vehicles/CarGen.cpp index 16401008..a1d58ab2 100644 --- a/src/vehicles/CarGen.cpp +++ b/src/vehicles/CarGen.cpp @@ -57,7 +57,8 @@ void CCarGenerator::DoInternalProcessing() mi = -m_nModelIndex; if (m_nModelIndex == -1 || !CStreaming::HasModelLoaded(mi)) { CZoneInfo pZone; - CTheZones::GetZoneInfoForTimeOfDay(&FindPlayerCoors(), &pZone); + CVector pos = FindPlayerCoors(); + CTheZones::GetZoneInfoForTimeOfDay(&pos, &pZone); mi = CCarCtrl::ChooseCarModel(CCarCtrl::ChooseCarRating(&pZone)); if (mi < 0) return; @@ -186,7 +187,7 @@ bool CCarGenerator::CheckForBlockage(int32 mi) CWorld::FindObjectsKindaColliding(CVector(m_vecPos), pColModel->boundingSphere.radius, 1, &entities, 8, pEntities, false, true, true, false, false); for (int i = 0; i < entities; i++) { if (m_vecPos.z + pColModel->boundingBox.min.z < pEntities[i]->GetPosition().z + pEntities[i]->GetColModel()->boundingBox.max.z + 1.0f && - m_vecPos.z + pColModel->boundingBox.max.z < pEntities[i]->GetPosition().z + pEntities[i]->GetColModel()->boundingBox.min.z - 1.0f) { + m_vecPos.z + pColModel->boundingBox.max.z > pEntities[i]->GetPosition().z + pEntities[i]->GetColModel()->boundingBox.min.z - 1.0f) { m_bIsBlocking = true; return true; } diff --git a/src/vehicles/Cranes.cpp b/src/vehicles/Cranes.cpp index 043f1c73..db7b514f 100644 --- a/src/vehicles/Cranes.cpp +++ b/src/vehicles/Cranes.cpp @@ -88,6 +88,7 @@ void CCranes::AddThisOneCrane(CEntity* pEntity) if (pCrane->m_nAudioEntity >= 0) DMAudio.SetEntityStatus(pCrane->m_nAudioEntity, 1); pCrane->m_bIsTop = (MODELID_CRANE_1 != pEntity->GetModelIndex()); +#if 0 // Is this used to avoid military crane? if (pCrane->m_bIsTop || pEntity->GetPosition().y > 0.0f) { CObject* pHook = new CObject(MI_MAGNET, false); @@ -100,6 +101,7 @@ void CCranes::AddThisOneCrane(CEntity* pEntity) pCrane->SetHookMatrix(); } else +#endif pCrane->m_pHook = nil; NumCranes++; } @@ -185,7 +187,7 @@ bool CCranes::IsThisCarPickedUp(float X, float Y, CVehicle* pVehicle) result = true; } } - return true; + return result; } void CCranes::UpdateCranes(void) @@ -244,8 +246,11 @@ void CCrane::Update(void) Abs(m_pVehiclePickedUp->GetMoveSpeed().x) > CAR_MOVING_SPEED_THRESHOLD || Abs(m_pVehiclePickedUp->GetMoveSpeed().y) > CAR_MOVING_SPEED_THRESHOLD || Abs(m_pVehiclePickedUp->GetMoveSpeed().z) > CAR_MOVING_SPEED_THRESHOLD || - FindPlayerPed()->GetPedState() == PED_ENTER_CAR && // TODO: fix carjack bug - FindPlayerPed()->m_pSeekTarget == m_pVehiclePickedUp) { + (FindPlayerPed()->GetPedState() == PED_ENTER_CAR +#ifdef FIX_BUGS + || FindPlayerPed()->GetPedState() == PED_CARJACK +#endif + ) && FindPlayerPed()->m_pSeekTarget == m_pVehiclePickedUp) { m_pVehiclePickedUp = nil; m_nCraneState = IDLE; } @@ -396,7 +401,7 @@ bool CCrane::RotateCarriedCarProperly() float fDeltaThisFrame = CAR_ROTATION_SPEED * CTimer::GetTimeStep(); if (Abs(fAngleDelta) <= fDeltaThisFrame) // no rotation is actually applied? return true; - m_pVehiclePickedUp->GetMatrix().RotateZ(Abs(fDeltaThisFrame)); + m_pVehiclePickedUp->GetMatrix().RotateZ(fAngleDelta < 0 ? -fDeltaThisFrame : fDeltaThisFrame); return false; } diff --git a/src/vehicles/HandlingMgr.cpp b/src/vehicles/HandlingMgr.cpp index cc6428e1..3d5d4e77 100644 --- a/src/vehicles/HandlingMgr.cpp +++ b/src/vehicles/HandlingMgr.cpp @@ -4,6 +4,8 @@ #include "FileMgr.h" #include "HandlingMgr.h" +//--MIAMI: done + cHandlingDataMgr mod_HandlingManager; const char *HandlingFilename = "HANDLING.CFG"; @@ -127,7 +129,7 @@ cHandlingDataMgr::Initialise(void) { LoadHandlingData(); field_0 = 0.1f; - field_4 = 0.9f; + fWheelFriction = 0.9f; field_8 = 1.0f; field_C = 0.8f; field_10 = 0.98f; @@ -143,6 +145,9 @@ cHandlingDataMgr::LoadHandlingData(void) int field, handlingId; int keepGoing; tHandlingData *handling; + tFlyingHandlingData *flyingHandling; + tBoatHandlingData *boatHandling; + tBikeHandlingData *bikeHandling; CFileMgr::SetDir("DATA"); CFileMgr::LoadFile(HandlingFilename, work_buff, sizeof(work_buff), "r"); @@ -151,6 +156,9 @@ cHandlingDataMgr::LoadHandlingData(void) start = (char*)work_buff; end = start+1; handling = nil; + flyingHandling = nil; + boatHandling = nil; + bikeHandling = nil; keepGoing = 1; while(keepGoing){ @@ -166,61 +174,158 @@ cHandlingDataMgr::LoadHandlingData(void) // yeah, this is kinda crappy if(strncmp(line, ";the end", 9) == 0) keepGoing = 0; -// else if(line[0] != ';'){ -// TODO(MIAMI): read boat, bike, flying values - else if(line[0] != ';' && line[0] != '%' && line[0] != '!' && line[0] != '$'){ - field = 0; - strcpy(delim, " \t"); - // FIX: game seems to use a do-while loop here - for(word = strtok(line, delim); word; word = strtok(nil, delim)){ - switch(field){ - case 0: - handlingId = FindExactWord(word, (const char*)VehicleNames, 14, NUMHANDLINGS); - assert(handlingId >= 0 && handlingId < NUMHANDLINGS); - handling = &HandlingData[handlingId]; - handling->nIdentifier = (eHandlingId)handlingId; - break; - case 1: handling->fMass = strtod(word, nil); break; - case 2: handling->Dimension.x = strtod(word, nil); break; - case 3: handling->Dimension.y = strtod(word, nil); break; - case 4: handling->Dimension.z = strtod(word, nil); break; - case 5: handling->CentreOfMass.x = strtod(word, nil); break; - case 6: handling->CentreOfMass.y = strtod(word, nil); break; - case 7: handling->CentreOfMass.z = strtod(word, nil); break; - case 8: handling->nPercentSubmerged = atoi(word); break; - case 9: handling->fTractionMultiplier = strtod(word, nil); break; - case 10: handling->fTractionLoss = strtod(word, nil); break; - case 11: handling->fTractionBias = strtod(word, nil); break; - case 12: handling->Transmission.nNumberOfGears = atoi(word); break; - case 13: handling->Transmission.fMaxVelocity = strtod(word, nil); break; - case 14: handling->Transmission.fEngineAcceleration = strtod(word, nil) * 0.4f; break; - case 15: handling->Transmission.nDriveType = word[0]; break; - case 16: handling->Transmission.nEngineType = word[0]; break; - case 17: handling->fBrakeDeceleration = strtod(word, nil); break; - case 18: handling->fBrakeBias = strtod(word, nil); break; - case 19: handling->bABS = !!atoi(word); break; - case 20: handling->fSteeringLock = strtod(word, nil); break; - case 21: handling->fSuspensionForceLevel = strtod(word, nil); break; - case 22: handling->fSuspensionDampingLevel = strtod(word, nil); break; - case 23: handling->fSeatOffsetDistance = strtod(word, nil); break; - case 24: handling->fCollisionDamageMultiplier = strtod(word, nil); break; - case 25: handling->nMonetaryValue = atoi(word); break; - case 26: handling->fSuspensionUpperLimit = strtod(word, nil); break; - case 27: handling->fSuspensionLowerLimit = strtod(word, nil); break; - case 28: handling->fSuspensionBias = strtod(word, nil); break; - case 29: - // TODO(MIAMI): suspension anti-dive multiplier - break; - case 30: - sscanf(word, "%x", &handling->Flags); - handling->Transmission.Flags = handling->Flags; - break; - case 31: handling->FrontLights = atoi(word); break; - case 32: handling->RearLights = atoi(word); break; + else if(line[0] != ';'){ + if(line[0] == '!'){ + // Bike data + field = 0; + strcpy(delim, " \t"); + // FIX: game seems to use a do-while loop here + for(word = strtok(line, delim); word; word = strtok(nil, delim)){ + switch(field){ + case 0: break; + case 1: + handlingId = FindExactWord(word, (const char*)VehicleNames, 14, NUMHANDLINGS); + assert(handlingId >= 0 && handlingId < NUMHANDLINGS); + bikeHandling = GetBikePointer(handlingId); + bikeHandling->nIdentifier = (eHandlingId)handlingId; + break; + case 2: bikeHandling->fLeanFwdCOM = atof(word); break; + case 3: bikeHandling->fLeanFwdForce = atof(word); break; + case 4: bikeHandling->fLeanBakCOM = atof(word); break; + case 5: bikeHandling->fLeanBackForce = atof(word); break; + case 6: bikeHandling->fMaxLean = atof(word); break; + case 7: bikeHandling->fFullAnimLean = atof(word); break; + case 8: bikeHandling->fDesLean = atof(word); break; + case 9: bikeHandling->fSpeedSteer = atof(word); break; + case 10: bikeHandling->fSlipSteer = atof(word); break; + case 11: bikeHandling->fNoPlayerCOMz = atof(word); break; + case 12: bikeHandling->fWheelieAng = atof(word); break; + case 13: bikeHandling->fStoppieAng = atof(word); break; + case 14: bikeHandling->fWheelieSteer = atof(word); break; + case 15: bikeHandling->fWheelieStabMult = atof(word); break; + case 16: bikeHandling->fStoppieStabMult = atof(word); break; + } + field++; } - field++; + ConvertBikeDataToGameUnits(bikeHandling); + }else if(line[0] == '$'){ + // Flying data + field = 0; + strcpy(delim, " \t"); + // FIX: game seems to use a do-while loop here + for(word = strtok(line, delim); word; word = strtok(nil, delim)){ + switch(field){ + case 0: break; + case 1: + handlingId = FindExactWord(word, (const char*)VehicleNames, 14, NUMHANDLINGS); + assert(handlingId >= 0 && handlingId < NUMHANDLINGS); + flyingHandling = GetFlyingPointer(handlingId); + flyingHandling->nIdentifier = (eHandlingId)handlingId; + break; + case 2: flyingHandling->fThrust = atof(word); break; + case 3: flyingHandling->fThrustFallOff = atof(word); break; + case 4: flyingHandling->fYaw = atof(word); break; + case 5: flyingHandling->fYawStab = atof(word); break; + case 6: flyingHandling->fSideSlip = atof(word); break; + case 7: flyingHandling->fRoll = atof(word); break; + case 8: flyingHandling->fRollStab = atof(word); break; + case 9: flyingHandling->fPitch = atof(word); break; + case 10: flyingHandling->fPitchStab = atof(word); break; + case 11: flyingHandling->fFormLift = atof(word); break; + case 12: flyingHandling->fAttackLift = atof(word); break; + case 13: flyingHandling->fMoveRes = atof(word); break; + case 14: flyingHandling->vecTurnRes.x = atof(word); break; + case 15: flyingHandling->vecTurnRes.y = atof(word); break; + case 16: flyingHandling->vecTurnRes.z = atof(word); break; + case 17: flyingHandling->vecSpeedRes.x = atof(word); break; + case 18: flyingHandling->vecSpeedRes.y = atof(word); break; + case 19: flyingHandling->vecSpeedRes.z = atof(word); break; + } + field++; + } + }else if(line[0] == '%'){ + // Boat data + field = 0; + strcpy(delim, " \t"); + // FIX: game seems to use a do-while loop here + for(word = strtok(line, delim); word; word = strtok(nil, delim)){ + switch(field){ + case 0: break; + case 1: + handlingId = FindExactWord(word, (const char*)VehicleNames, 14, NUMHANDLINGS); + assert(handlingId >= 0 && handlingId < NUMHANDLINGS); + boatHandling = GetBoatPointer(handlingId); + boatHandling->nIdentifier = (eHandlingId)handlingId; + break; + case 2: boatHandling->fThrustY = atof(word); break; + case 3: boatHandling->fThrustZ = atof(word); break; + case 4: boatHandling->fThrustAppZ = atof(word); break; + case 5: boatHandling->fAqPlaneForce = atof(word); break; + case 6: boatHandling->fAqPlaneLimit = atof(word); break; + case 7: boatHandling->fAqPlaneOffset = atof(word); break; + case 8: boatHandling->fWaveAudioMult = atof(word); break; + case 9: boatHandling->vecMoveRes.x = atof(word); break; + case 10: boatHandling->vecMoveRes.y = atof(word); break; + case 11: boatHandling->vecMoveRes.z = atof(word); break; + case 12: boatHandling->vecTurnRes.x = atof(word); break; + case 13: boatHandling->vecTurnRes.y = atof(word); break; + case 14: boatHandling->vecTurnRes.z = atof(word); break; + case 15: boatHandling->fLook_L_R_BehindCamHeight = atof(word); break; + } + field++; + } + }else{ + field = 0; + strcpy(delim, " \t"); + // FIX: game seems to use a do-while loop here + for(word = strtok(line, delim); word; word = strtok(nil, delim)){ + switch(field){ + case 0: + handlingId = FindExactWord(word, (const char*)VehicleNames, 14, NUMHANDLINGS); + assert(handlingId >= 0 && handlingId < NUMHANDLINGS); + handling = &HandlingData[handlingId]; + handling->nIdentifier = (eHandlingId)handlingId; + break; + case 1: handling->fMass = atof(word); break; + case 2: handling->Dimension.x = atof(word); break; + case 3: handling->Dimension.y = atof(word); break; + case 4: handling->Dimension.z = atof(word); break; + case 5: handling->CentreOfMass.x = atof(word); break; + case 6: handling->CentreOfMass.y = atof(word); break; + case 7: handling->CentreOfMass.z = atof(word); break; + case 8: handling->nPercentSubmerged = atoi(word); break; + case 9: handling->fTractionMultiplier = atof(word); break; + case 10: handling->fTractionLoss = atof(word); break; + case 11: handling->fTractionBias = atof(word); break; + case 12: handling->Transmission.nNumberOfGears = atoi(word); break; + case 13: handling->Transmission.fMaxVelocity = atof(word); break; + case 14: handling->Transmission.fEngineAcceleration = atof(word) * 0.4f; break; + case 15: handling->Transmission.nDriveType = word[0]; break; + case 16: handling->Transmission.nEngineType = word[0]; break; + case 17: handling->fBrakeDeceleration = atof(word); break; + case 18: handling->fBrakeBias = atof(word); break; + case 19: handling->bABS = !!atoi(word); break; + case 20: handling->fSteeringLock = atof(word); break; + case 21: handling->fSuspensionForceLevel = atof(word); break; + case 22: handling->fSuspensionDampingLevel = atof(word); break; + case 23: handling->fSeatOffsetDistance = atof(word); break; + case 24: handling->fCollisionDamageMultiplier = atof(word); break; + case 25: handling->nMonetaryValue = atoi(word); break; + case 26: handling->fSuspensionUpperLimit = atof(word); break; + case 27: handling->fSuspensionLowerLimit = atof(word); break; + case 28: handling->fSuspensionBias = atof(word); break; + case 29: handling->fSuspensionAntidiveMultiplier = atof(word); break; + case 30: + sscanf(word, "%x", &handling->Flags); + handling->Transmission.Flags = handling->Flags; + break; + case 31: handling->FrontLights = atoi(word); break; + case 32: handling->RearLights = atoi(word); break; + } + field++; + } + ConvertDataToGameUnits(handling); } - ConvertDataToGameUnits(handling); } } } @@ -253,6 +358,7 @@ cHandlingDataMgr::ConvertDataToGameUnits(tHandlingData *handling) if(handling->fTurnMass < 10.0f) handling->fTurnMass *= 5.0f; handling->fInvMass = 1.0f/handling->fMass; + handling->fCollisionDamageMultiplier *= 2000.0f/handling->fMass; handling->fBuoyancy = 100.0f/handling->nPercentSubmerged * 0.008f*handling->fMass; // What the hell is going on here? @@ -268,11 +374,16 @@ cHandlingDataMgr::ConvertDataToGameUnits(tHandlingData *handling) if(handling->nIdentifier == HANDLING_RCBANDIT){ handling->Transmission.fUnkMaxVelocity = handling->Transmission.fMaxVelocity; + handling->Transmission.fMaxReverseVelocity = -handling->Transmission.fMaxVelocity; + }else if(handling->nIdentifier >= HANDLING_BIKE && handling->nIdentifier <= HANDLING_FREEWAY){ + handling->Transmission.fUnkMaxVelocity = velocity; + handling->Transmission.fMaxVelocity = velocity * 1.2f; + handling->Transmission.fMaxReverseVelocity = -0.05f; }else{ handling->Transmission.fUnkMaxVelocity = velocity; handling->Transmission.fMaxVelocity = velocity * 1.2f; + handling->Transmission.fMaxReverseVelocity = -0.2f; } - handling->Transmission.fMaxReverseVelocity = -0.2f; if(handling->Transmission.nDriveType == '4') handling->Transmission.fEngineAcceleration /= 4.0f; @@ -282,6 +393,15 @@ cHandlingDataMgr::ConvertDataToGameUnits(tHandlingData *handling) handling->Transmission.InitGearRatios(); } +void +cHandlingDataMgr::ConvertBikeDataToGameUnits(tBikeHandlingData *handling) +{ + handling->fMaxLean = Sin(DEGTORAD(handling->fMaxLean)); + handling->fFullAnimLean = DEGTORAD(handling->fFullAnimLean); + handling->fWheelieAng = Sin(DEGTORAD(handling->fWheelieAng)); + handling->fStoppieAng = Sin(DEGTORAD(handling->fStoppieAng)); +} + int32 cHandlingDataMgr::GetHandlingId(const char *name) { @@ -291,3 +411,19 @@ cHandlingDataMgr::GetHandlingId(const char *name) break; return i; } + +tFlyingHandlingData* +cHandlingDataMgr::GetFlyingPointer(uint8 id) +{ + if(id >= HANDLING_SEAPLANE && id <= HANDLING_RCCOPTER) + return &FlyingHandlingData[id-HANDLING_SEAPLANE]; + return &FlyingHandlingData[0]; +} + +tBoatHandlingData* +cHandlingDataMgr::GetBoatPointer(uint8 id) +{ + if(id >= HANDLING_PREDATOR && id <= HANDLING_SEAPLANE) + return &BoatHandlingData[id-HANDLING_PREDATOR]; + return &BoatHandlingData[0]; +} diff --git a/src/vehicles/HandlingMgr.h b/src/vehicles/HandlingMgr.h index e629d885..e93f7879 100644 --- a/src/vehicles/HandlingMgr.h +++ b/src/vehicles/HandlingMgr.h @@ -85,11 +85,13 @@ enum eHandlingId HANDLING_LOVEFIST, HANDLING_BLOODRA, HANDLING_BLOODRB, + HANDLING_BIKE, HANDLING_MOPED, HANDLING_DIRTBIKE, HANDLING_ANGEL, HANDLING_FREEWAY, + HANDLING_PREDATOR, HANDLING_SPEEDER, HANDLING_REEFER, @@ -100,7 +102,7 @@ enum eHandlingId HANDLING_DINGHY, HANDLING_MARQUIS, HANDLING_CUPBOAT, - HANDLING_SEAPLANE, + HANDLING_SEAPLANE, // both boat and plane! HANDLING_SPARROW, HANDLING_SEASPAR, HANDLING_MAVERICK, @@ -109,7 +111,13 @@ enum eHandlingId HANDLING_HUNTER, HANDLING_RCBARON, HANDLING_RCGOBLIN, - HANDLING_RCCOPTER + HANDLING_RCCOPTER, + + NUMHANDLINGS, + + NUMBIKEHANDLINGS = HANDLING_FREEWAY+1 - HANDLING_BIKE, + NUMFLYINGHANDLINGS = HANDLING_RCCOPTER+1 - HANDLING_SEAPLANE, + NUMBOATHANDLINGS = HANDLING_SEAPLANE+1 - HANDLING_PREDATOR, }; enum @@ -168,6 +176,7 @@ struct tHandlingData float fSuspensionUpperLimit; float fSuspensionLowerLimit; float fSuspensionBias; + float fSuspensionAntidiveMultiplier; float fCollisionDamageMultiplier; uint32 Flags; float fSeatOffsetDistance; @@ -175,19 +184,74 @@ struct tHandlingData int8 FrontLights; int8 RearLights; }; -VALIDATE_SIZE(tHandlingData, 0xD8); + +struct tBikeHandlingData +{ + eHandlingId nIdentifier; + float fLeanFwdCOM; + float fLeanFwdForce; + float fLeanBakCOM; + float fLeanBackForce; + float fMaxLean; + float fFullAnimLean; + float fDesLean; + float fSpeedSteer; + float fSlipSteer; + float fNoPlayerCOMz; + float fWheelieAng; + float fStoppieAng; + float fWheelieSteer; + float fWheelieStabMult; + float fStoppieStabMult; +}; + +struct tBoatHandlingData +{ + eHandlingId nIdentifier; + float fThrustY; + float fThrustZ; + float fThrustAppZ; + float fAqPlaneForce; + float fAqPlaneLimit; + float fAqPlaneOffset; + float fWaveAudioMult; + float fLook_L_R_BehindCamHeight; + CVector vecMoveRes; + CVector vecTurnRes; +}; + +struct tFlyingHandlingData +{ + eHandlingId nIdentifier; + float fThrust; + float fThrustFallOff; + float fYaw; + float fYawStab; + float fSideSlip; + float fRoll; + float fRollStab; + float fPitch; + float fPitchStab; + float fFormLift; + float fAttackLift; + float fMoveRes; + CVector vecTurnRes; + CVector vecSpeedRes; +}; class cHandlingDataMgr { float field_0; // unused it seems public: - float field_4; // wheel related + float fWheelFriction; // wheel related private: float field_8; // float field_C; // unused it seems float field_10; // tHandlingData HandlingData[NUMHANDLINGS]; - uint32 field_302C; // unused it seems + tBikeHandlingData BikeHandlingData[NUMBIKEHANDLINGS]; + tFlyingHandlingData FlyingHandlingData[NUMFLYINGHANDLINGS]; + tBoatHandlingData BoatHandlingData[NUMBOATHANDLINGS]; public: cHandlingDataMgr(void); @@ -195,8 +259,12 @@ public: void LoadHandlingData(void); int FindExactWord(const char *word, const char *words, int wordLen, int numWords); void ConvertDataToGameUnits(tHandlingData *handling); + void ConvertBikeDataToGameUnits(tBikeHandlingData *handling); int32 GetHandlingId(const char *name); tHandlingData *GetHandlingData(eHandlingId id) { return &HandlingData[id]; } + tBikeHandlingData *GetBikePointer(uint8 id) { return &BikeHandlingData[id-HANDLING_BIKE]; } + tFlyingHandlingData *GetFlyingPointer(uint8 id); + tBoatHandlingData *GetBoatPointer(uint8 id); bool HasRearWheelDrive(eHandlingId id) { return HandlingData[id].Transmission.nDriveType == 'R'; } bool HasFrontWheelDrive(eHandlingId id) { return HandlingData[id].Transmission.nDriveType == 'F'; } }; diff --git a/src/vehicles/Heli.cpp b/src/vehicles/Heli.cpp index 5cd6488a..1e0a8c27 100644 --- a/src/vehicles/Heli.cpp +++ b/src/vehicles/Heli.cpp @@ -558,60 +558,8 @@ CHeli::ProcessControl(void) void CHeli::PreRender(void) { - float angle; - uint8 i; - CColPoint point; - CEntity *entity; - uint8 r, g, b; - float testLowZ = FindPlayerCoors().z - 10.0f; float radius = (GetPosition().z - FindPlayerCoors().z - 10.0f - 1.0f) * 0.3f + 10.0f; - int frm = CTimer::GetFrameCounter() & 7; - - i = 0; - for(angle = 0.0f; angle < TWOPI; angle += TWOPI/32){ - CVector pos(radius*Cos(angle), radius*Sin(angle), 0.0f); - CVector dir = pos*0.01f; - pos += GetPosition(); - - if(CWorld::ProcessVerticalLine(pos, testLowZ, point, entity, true, false, false, false, true, false, nil)) - m_fHeliDustZ[frm] = point.point.z; - else - m_fHeliDustZ[frm] = -101.0f; - - switch(point.surfaceB){ - default: - case SURFACE_TARMAC: - r = 10; - g = 10; - b = 10; - break; - case SURFACE_GRASS: - r = 10; - g = 6; - b = 3; - break; - case SURFACE_DIRT: - r = 10; - g = 8; - b = 7; - break; - case SURFACE_DIRTTRACK: - r = 10; - g = 6; - b = 3; - break; - } - RwRGBA col = { r, g, b, 32 }; -#ifdef FIX_BUGS - pos.z = m_fHeliDustZ[frm]; -#else - // What the hell is the point of this? - pos.z = m_fHeliDustZ[(i - (i&3))/4]; // advance every 4 iterations, why not just /4? -#endif - if(pos.z > -200.0f && GetPosition().z - pos.z < 20.0f) - CParticle::AddParticle(PARTICLE_HELI_DUST, pos, dir, nil, 0.0f, col); - i++; - } + HeliDustGenerate(this, radius, FindPlayerCoors().z, Max(16.0f - 4.0f*CTimer::GetTimeStep(), 2.0f)); } void diff --git a/src/vehicles/Plane.cpp b/src/vehicles/Plane.cpp index 39069364..8f32f12a 100644 --- a/src/vehicles/Plane.cpp +++ b/src/vehicles/Plane.cpp @@ -735,6 +735,7 @@ CPlane::InitPlanes(void) TotalDurationOfFlightPath2 = TotalLengthOfFlightPath2/CRUISE_SPEED; } +/* // Mission Cesna if(pPath3Nodes == nil){ pPath3Nodes = LoadPath("data\\paths\\flight3.dat", NumPath3Nodes, TotalLengthOfFlightPath3, false); @@ -746,6 +747,7 @@ CPlane::InitPlanes(void) pPath4Nodes = LoadPath("data\\paths\\flight4.dat", NumPath4Nodes, TotalLengthOfFlightPath4, false); TotalDurationOfFlightPath4 = TotalLengthOfFlightPath4/CRUISE_SPEED; } +*/ CStreaming::LoadAllRequestedModels(false); CStreaming::RequestModel(MI_AIRTRAIN, 0); diff --git a/src/vehicles/Vehicle.cpp b/src/vehicles/Vehicle.cpp index 4149fe6c..1dc7af11 100644 --- a/src/vehicles/Vehicle.cpp +++ b/src/vehicles/Vehicle.cpp @@ -14,11 +14,22 @@ #include "Lights.h" #include "PointLights.h" #include "Renderer.h" +#include "VisibilityPlugins.h" #include "DMAudio.h" #include "Radar.h" #include "Fire.h" #include "Darkel.h" #include "Streaming.h" +#include "Camera.h" +#include "Stats.h" +#include "Garages.h" +#include "Wanted.h" +#include "SurfaceTable.h" +#include "Particle.h" +#include "WaterLevel.h" +#include "Timecycle.h" +#include "Weather.h" +#include "Coronas.h" bool CVehicle::bWheelsOnlyCheat; bool CVehicle::bAllDodosCheat; @@ -29,6 +40,8 @@ bool CVehicle::bCheat5; bool CVehicle::bAltDodoCheat; #endif bool CVehicle::m_bDisableMouseSteering = true; +bool CVehicle::bDisableRemoteDetonation; +bool CVehicle::bDisableRemoteDetonationOnContact; void *CVehicle::operator new(size_t sz) { return CPools::GetVehiclePool()->New(); } void *CVehicle::operator new(size_t sz, int handle) { return CPools::GetVehiclePool()->New(handle); } @@ -51,8 +64,8 @@ CVehicle::CVehicle(uint8 CreatedBy) { int i; - m_nCurrentGear = 0; - m_fChangeGearTime = 0; + m_nCurrentGear = 1; + m_fChangeGearTime = 0.0f; m_fSteerRatio = 0.0f; m_type = ENTITY_TYPE_VEHICLE; VehicleCreatedBy = CreatedBy; @@ -101,9 +114,26 @@ CVehicle::CVehicle(uint8 CreatedBy) m_bSirenOrAlarm = 0; m_nCarHornTimer = 0; m_nCarHornPattern = 0; + m_nCarHornDelay = 0; bPartOfConvoy = false; + bHeliMinimumTilt = false; + bAudioChangingGear = false; + bIsDrowning = false; + bTyresDontBurst = false; bCreatedAsPoliceVehicle = false; + bRestingOnPhysical = false; bParking = false; + bCanPark = CGeneral::GetRandomNumberInRange(0.0f, 1.0f) < 0.0f; // BUG? this makes no sense + bIsVan = false; + bIsBus = false; + bIsBig = false; + bLowVehicle = false; + + m_bombType = CARBOMB_NONE; + bDriverLastFrame = false; + m_pBombRigger = nil; + + m_nSetPieceExtendedRangeTime = 0; m_nAlarmState = 0; m_nDoorLock = CARLOCK_UNLOCKED; m_nLastWeaponDamage = -1; @@ -111,6 +141,7 @@ CVehicle::CVehicle(uint8 CreatedBy) m_audioEntityId = DMAudio.CreateEntity(AUDIOTYPE_PHYSICAL, this); if(m_audioEntityId >= 0) DMAudio.SetEntityStatus(m_audioEntityId, true); +// TODO(MIAMI): m_nRadioStation = CGeneral::GetRandomNumber() % USERTRACK; m_pCurGroundEntity = nil; m_bRainAudioCounter = 0; @@ -188,57 +219,30 @@ CVehicle::RemoveLighting(bool reset) CRenderer::RemoveVehiclePedLights(this, reset); } +bool +CVehicle::IsClearToDriveAway(void) +{ + CColPoint point; + float length = GetColModel()->boundingBox.GetSize().y; + CEntity *ent = nil; + CVector front = GetForward() * (length*0.5f + 3.0f); + return !CWorld::ProcessLineOfSight(GetPosition() + front, GetPosition(), + point, ent, true, true, false, false, false, true, true) || + ent == this; +} + float CVehicle::GetHeightAboveRoad(void) { return -1.0f * GetColModel()->boundingBox.min.z; } -const float fRCPropFallOff = 3.0f; -const float fRCAeroThrust = 0.003f; -const float fRCSideSlipMult = 0.1f; -const float fRCRudderMult = 0.2f; -const float fRCYawMult = -0.01f; -const float fRCRollMult = 0.02f; -const float fRCRollStabilise = -0.08f; -const float fRCPitchMult = 0.005f; -const float fRCTailMult = 0.3f; -const float fRCFormLiftMult = 0.02f; -const float fRCAttackLiftMult = 0.25f; -const CVector vecRCAeroResistance(0.998f, 0.998f, 0.9f); - -const float fSeaPropFallOff = 2.3f; -const float fSeaThrust = 0.002f; -const float fSeaSideSlipMult = 0.1f; -const float fSeaRudderMult = 0.01f; -const float fSeaYawMult = -0.0003f; -const float fSeaRollMult = 0.0015f; -const float fSeaRollStabilise = -0.01f; -const float fSeaPitchMult = 0.0002f; -const float fSeaTailMult = 0.01f; -const float fSeaFormLiftMult = 0.012f; -const float fSeaAttackLiftMult = 0.1f; -const CVector vecSeaAeroResistance(0.995f, 0.995f, 0.85f); - -const float fSpeedResistanceY = 500.0f; -const float fSpeedResistanceZ = 500.0f; - -const CVector vecHeliMoveRes(0.995f, 0.995f, 0.99f); -const CVector vecRCHeliMoveRes(0.99f, 0.99f, 0.99f); -const float fThrustVar = 0.3f; -const float fRotorFallOff = 0.75f; -const float fStabiliseVar = 0.015f; -const float fPitchBrake = 10.0f; -const float fPitchVar = 0.006f; -const float fRollVar = 0.006f; -const float fYawVar = -0.001f; -const CVector vecHeliResistance(0.81f, 0.85f, 0.99f); -const CVector vecRCHeliResistance(0.92f, 0.92f, 0.998f); -const float fSpinSpeedRes = 20.0f; - void CVehicle::FlyingControl(eFlightModel flightModel) { + if(pFlyingHandling == nil) + return; + switch(flightModel){ case FLIGHT_MODEL_DODO: { @@ -279,6 +283,8 @@ CVehicle::FlyingControl(eFlightModel flightModel) m_vecTurnSpeed.y *= Pow(0.9f, CTimer::GetTimeStep()); + + moveSpeed = m_vecMoveSpeed.MagnitudeSqr(); if(moveSpeed > SQR(1.5f)) m_vecMoveSpeed *= 1.5f/Sqrt(moveSpeed); @@ -286,172 +292,199 @@ CVehicle::FlyingControl(eFlightModel flightModel) float turnSpeed = m_vecTurnSpeed.MagnitudeSqr(); if(turnSpeed > SQR(0.2f)) m_vecTurnSpeed *= 0.2f/Sqrt(turnSpeed); - } break; + } case FLIGHT_MODEL_RCPLANE: case FLIGHT_MODEL_SEAPLANE: + case FLIGHT_MODEL_PLANE_UNUSED: + case FLIGHT_MODEL_PLANE: { + float fSteerLR = CPad::GetPad(0)->GetSteeringLeftRight() / 128.0f; + float fSteerUD = -CPad::GetPad(0)->GetSteeringUpDown() / 128.0f; + float fGunUD = Abs(CPad::GetPad(0)->GetCarGunUpDown()); + if(fGunUD > 1.0f) + fSteerUD = -CPad::GetPad(0)->GetCarGunUpDown() / 128.0f; + + float fSteerAngle = Atan2(fSteerUD, fSteerLR); + float fSteerMult = 1.0f; + if(fSteerAngle > -PI/4.0f && fSteerAngle <= PI/4.0f) + fSteerMult = 1.0f/Cos(fSteerAngle); + else if(fSteerAngle > PI/4.0f && fSteerAngle <= PI*3.0f/4.0f) + fSteerMult = 1.0f/Cos(fSteerAngle - HALFPI); + else if(fSteerAngle > PI*3.0f/4.0f) + fSteerMult = 1.0f/Cos(fSteerAngle - PI); + else if(fSteerAngle <= -PI*3.0f/4.0f) + fSteerMult = 1.0f/Cos(fSteerAngle + PI); + else if(fSteerAngle > -PI*3.0f/4.0f && fSteerAngle < -PI/4.0f) + fSteerMult = 1.0f/Cos(fSteerAngle + HALFPI); + + fSteerLR *= fSteerMult; + fSteerUD *= -fSteerMult; + // thrust float fForwSpeed = DotProduct(GetMoveSpeed(), GetForward()); CVector vecWidthForward = GetColModel()->boundingBox.min.y * GetForward(); float fThrust = (CPad::GetPad(0)->GetAccelerate() - CPad::GetPad(0)->GetBrake()) / 255.0f; - if (fForwSpeed > 0.1f || (flightModel == FLIGHT_MODEL_RCPLANE && fForwSpeed > 0.02f)) - fThrust += 1.0f; - else if (fForwSpeed > 0.0f && fThrust < 0.0f) - fThrust = 0.0f; - float fThrustImpulse; - if (flightModel == FLIGHT_MODEL_RCPLANE) - fThrustImpulse = (fThrust - fRCPropFallOff * fForwSpeed) * fRCAeroThrust; + float fThrustAccel; + if(fForwSpeed > 0.0f || fThrust > 0.0f) + fThrustAccel = (fThrust - pFlyingHandling->fThrustFallOff * fForwSpeed) * pFlyingHandling->fThrust; else - fThrustImpulse = (fThrust - fSeaPropFallOff * fForwSpeed) * fSeaThrust; - ApplyMoveForce(fThrustImpulse * GetForward() * m_fMass * CTimer::GetTimeStep()); + fThrustAccel = Min(fThrust - 8.0f * pFlyingHandling->fThrustFallOff * fForwSpeed, 0.0f) * pFlyingHandling->fThrust; + if(flightModel == FLIGHT_MODEL_PLANE_UNUSED) + fThrustAccel *= 0.3f; + else if(flightModel == FLIGHT_MODEL_PLANE) + fThrustAccel *= 0.1f; + ApplyMoveForce(fThrustAccel * GetForward() * m_fMass * CTimer::GetTimeStep()); // left/right float fSideSpeed = -DotProduct(GetMoveSpeed(), GetRight()); - float fSteerLR = CPad::GetPad(0)->GetSteeringLeftRight() / 128.0f; - float fSideSlipImpulse; - if (flightModel == FLIGHT_MODEL_RCPLANE) - fSideSlipImpulse = Abs(fSideSpeed) * fSideSpeed * fRCSideSlipMult; - else - fSideSlipImpulse = Abs(fSideSpeed) * fSideSpeed * fSeaSideSlipMult; - ApplyMoveForce(m_fMass * GetRight() * fSideSlipImpulse * CTimer::GetTimeStep()); + float fSideSlipAccel = pFlyingHandling->fSideSlip * fSideSpeed * Abs(fSideSpeed); + ApplyMoveForce(m_fMass * GetRight() * fSideSlipAccel * CTimer::GetTimeStep()); - float fYaw = -DotProduct(CrossProduct(m_vecTurnSpeed + m_vecTurnFriction, vecWidthForward) + m_vecMoveSpeed + m_vecMoveFriction, GetRight()); - float fYawImpulse; - if (flightModel == FLIGHT_MODEL_RCPLANE) - fYawImpulse = fRCRudderMult * fYaw * Abs(fYaw) + fRCYawMult * fSteerLR * fForwSpeed; - else - fYawImpulse = fSeaRudderMult * fYaw * Abs(fYaw) + fSeaYawMult * fSteerLR * fForwSpeed; - ApplyTurnForce(fYawImpulse * GetRight() * m_fTurnMass * CTimer::GetTimeStep(), vecWidthForward); + float fYaw = -DotProduct(GetSpeed(vecWidthForward), GetRight()); + float fYawAccel = pFlyingHandling->fYawStab * fYaw * Abs(fYaw) + pFlyingHandling->fYaw * fSteerLR * fForwSpeed; + ApplyTurnForce(fYawAccel * GetRight() * m_fTurnMass * CTimer::GetTimeStep(), vecWidthForward); - float fRollImpulse; + float fRollAccel; if (flightModel == FLIGHT_MODEL_RCPLANE) { float fDirectionMultiplier = CPad::GetPad(0)->GetLookRight(); if (CPad::GetPad(0)->GetLookLeft()) fDirectionMultiplier = -1; - fRollImpulse = (0.5f * fDirectionMultiplier + fSteerLR) * fRCRollMult; + fRollAccel = (0.5f * fDirectionMultiplier + fSteerLR) * pFlyingHandling->fRoll; } else - fRollImpulse = fSteerLR * fSeaRollMult; - ApplyTurnForce(GetRight() * fRollImpulse * fForwSpeed * m_fTurnMass * CTimer::GetTimeStep(), GetUp()); + fRollAccel = fSteerLR * pFlyingHandling->fRoll; + ApplyTurnForce(GetRight() * fRollAccel * fForwSpeed * m_fTurnMass * CTimer::GetTimeStep(), GetUp()); CVector vecFRight = CrossProduct(GetForward(), CVector(0.0f, 0.0f, 1.0f)); CVector vecStabilise = (GetUp().z > 0.0f) ? vecFRight : -vecFRight; float fStabiliseDirection = (GetRight().z > 0.0f) ? -1.0f : 1.0f; - float fStabiliseImpulse; - if (flightModel == FLIGHT_MODEL_RCPLANE) - fStabiliseImpulse = fRCRollStabilise * fStabiliseDirection * (1.0f - DotProduct(GetRight(), vecStabilise)) * (1.0f - Abs(GetForward().z)); - else - fStabiliseImpulse = fSeaRollStabilise * fStabiliseDirection * (1.0f - DotProduct(GetRight(), vecStabilise)) * (1.0f - Abs(GetForward().z)); - ApplyTurnForce(fStabiliseImpulse * m_fTurnMass * GetRight(), GetUp()); // no CTimer::GetTimeStep(), is it right? VC doesn't have it too + float fStabiliseSpeed = pFlyingHandling->fRollStab * fStabiliseDirection * (1.0f - DotProduct(GetRight(), vecStabilise)) * (1.0f - Abs(GetForward().z)); + ApplyTurnForce(fStabiliseSpeed * m_fTurnMass * GetRight(), GetUp()); // no CTimer::GetTimeStep(), is it right? // up/down - float fTail = -DotProduct(CrossProduct(m_vecTurnSpeed + m_vecTurnFriction, vecWidthForward) + m_vecMoveSpeed + m_vecMoveFriction, GetUp()); - float fSteerUD = -CPad::GetPad(0)->GetSteeringUpDown() / 128.0f; - float fPitchImpulse; - if (flightModel == FLIGHT_MODEL_RCPLANE) - fPitchImpulse = fRCTailMult * fTail * Abs(fTail) + fRCPitchMult * fSteerUD * fForwSpeed; - else - fPitchImpulse = fSeaTailMult * fTail * Abs(fTail) + fSeaPitchMult * fSteerUD * fForwSpeed; - ApplyTurnForce(fPitchImpulse * m_fTurnMass * GetUp() * CTimer::GetTimeStep(), vecWidthForward); + float fTail = -DotProduct(GetSpeed(vecWidthForward), GetUp()); + float fPitchAccel = pFlyingHandling->fPitchStab * fTail * Abs(fTail) + pFlyingHandling->fPitch * fSteerUD * fForwSpeed; + ApplyTurnForce(fPitchAccel * m_fTurnMass * GetUp() * CTimer::GetTimeStep(), vecWidthForward); float fLift = -DotProduct(GetMoveSpeed(), GetUp()) / Max(0.01f, GetMoveSpeed().Magnitude()); - float fLiftImpluse; - if (flightModel == FLIGHT_MODEL_RCPLANE) - fLiftImpluse = (fRCAttackLiftMult * fLift + fRCFormLiftMult) * fForwSpeed * fForwSpeed; - else - fLiftImpluse = (fSeaAttackLiftMult * fLift + fSeaFormLiftMult) * fForwSpeed * fForwSpeed; - float fLiftForce = fLiftImpluse * m_fMass * CTimer::GetTimeStep(); - if (GRAVITY * CTimer::GetTimeStep() * m_fMass < fLiftImpluse) { + float fLiftAccel = (pFlyingHandling->fAttackLift * fLift + pFlyingHandling->fFormLift) * fForwSpeed * fForwSpeed; + float fLiftImpulse = fLiftAccel * m_fMass * CTimer::GetTimeStep(); + if (GRAVITY * CTimer::GetTimeStep() * m_fMass < fLiftImpulse) { if (flightModel == FLIGHT_MODEL_RCPLANE && GetPosition().z > 50.0f) - fLiftForce = CTimer::GetTimeStep() * 0.0072 * m_fMass; + fLiftImpulse = CTimer::GetTimeStep() * 0.9f*GRAVITY * m_fMass; else if (flightModel == FLIGHT_MODEL_SEAPLANE && GetPosition().z > 80.0f) - fLiftForce = CTimer::GetTimeStep() * 0.0072 * m_fMass; + fLiftImpulse = CTimer::GetTimeStep() * 0.9f*GRAVITY * m_fMass; } - ApplyMoveForce(fLiftForce * GetUp()); + ApplyMoveForce(fLiftImpulse * GetUp()); + CVector vecResistance; - if (flightModel == FLIGHT_MODEL_RCPLANE) - vecResistance = vecRCAeroResistance; - else - vecResistance = vecSeaAeroResistance; + vecResistance = pFlyingHandling->vecTurnRes; float rX = Pow(vecResistance.x, CTimer::GetTimeStep()); float rY = Pow(vecResistance.y, CTimer::GetTimeStep()); float rZ = Pow(vecResistance.z, CTimer::GetTimeStep()); CVector vecTurnSpeed = Multiply3x3(m_vecTurnSpeed, GetMatrix()); vecTurnSpeed.x *= rX; - float fResistance = vecTurnSpeed.y * (1.0f / (fSpeedResistanceY * SQR(vecTurnSpeed.y) + 1.0f)) * rY - vecTurnSpeed.y; + float fResistance = vecTurnSpeed.y * (1.0f / (pFlyingHandling->vecSpeedRes.y * SQR(vecTurnSpeed.y) + 1.0f)) * rY - vecTurnSpeed.y; vecTurnSpeed.z *= rZ; m_vecTurnSpeed = Multiply3x3(GetMatrix(), vecTurnSpeed); ApplyTurnForce(-GetUp() * fResistance * m_fTurnMass, GetRight() + Multiply3x3(GetMatrix(), m_vecCentreOfMass)); + + + float fMoveSpeed = m_vecMoveSpeed.MagnitudeSqr(); + if(fMoveSpeed > SQR(1.5f)) + m_vecMoveSpeed *= 1.5f/Sqrt(fMoveSpeed); + + float fTurnSpeed = m_vecTurnSpeed.MagnitudeSqr(); + if(fTurnSpeed > SQR(0.2f)) + m_vecTurnSpeed *= 0.2f/Sqrt(fTurnSpeed); break; } + case FLIGHT_MODEL_RCHELI: case FLIGHT_MODEL_HELI: { - CVector vecMoveResistance; - if (GetModelIndex() == MI_SPARROW) - vecMoveResistance = vecHeliMoveRes; - else - vecMoveResistance = vecRCHeliMoveRes; - float rmX = Pow(vecMoveResistance.x, CTimer::GetTimeStep()); - float rmY = Pow(vecMoveResistance.y, CTimer::GetTimeStep()); - float rmZ = Pow(vecMoveResistance.z, CTimer::GetTimeStep()); - m_vecMoveSpeed.x *= rmX; - m_vecMoveSpeed.y *= rmY; - m_vecMoveSpeed.z *= rmZ; + float rm = Pow(pFlyingHandling->fMoveRes, CTimer::GetTimeStep()); + m_vecMoveSpeed *= rm; if (GetStatus() != STATUS_PLAYER && GetStatus() != STATUS_PLAYER_REMOTE) return; - float fThrust; - if (bCheat5) - fThrust = CPad::GetPad(0)->GetSteeringUpDown() * fThrustVar / 128.0f + 0.95f; - else - fThrust = fThrustVar * (CPad::GetPad(0)->GetAccelerate() - 2 * CPad::GetPad(0)->GetBrake()) / 255.0f + 0.95f; - fThrust -= fRotorFallOff * DotProduct(m_vecMoveSpeed, GetUp()); -#ifdef GTA3_1_1_PATCH - if (fThrust > 0.9f && GetPosition().z > 80.0f) - fThrust = 0.9f; -#endif + float fUpSpeed = DotProduct(m_vecMoveSpeed, GetUp()); + float fThrust = (CPad::GetPad(0)->GetAccelerate() - CPad::GetPad(0)->GetBrake()) / 255.0f; + if(fThrust < 0.0f) + fThrust *= 2.0f; + if(flightModel == FLIGHT_MODEL_RCHELI){ + fThrust = pFlyingHandling->fThrust * fThrust + 0.45f; + ApplyMoveForce(GRAVITY * CVector(0.0f, 0.0f, 0.5f) * m_fMass * CTimer::GetTimeStep()); + }else + fThrust = pFlyingHandling->fThrust * fThrust + 0.95f; + fThrust -= pFlyingHandling->fThrustFallOff * fUpSpeed; + if(flightModel == FLIGHT_MODEL_RCHELI && GetPosition().z > 40.0f) + fThrust *= 10.0f/(GetPosition().z - 30.0f); + else if(GetPosition().z > 80.0f) + fThrust *= 10.0f/(GetPosition().z - 70.0f); ApplyMoveForce(GRAVITY * GetUp() * fThrust * m_fMass * CTimer::GetTimeStep()); - if (GetUp().z > 0.0f) - ApplyTurnForce(-CVector(GetUp().x, GetUp().y, 0.0f) * fStabiliseVar * m_fTurnMass * CTimer::GetTimeStep(), GetUp()); + if (GetUp().z > 0.0f){ + float upRight = clamp(GetRight().z, -pFlyingHandling->fFormLift, pFlyingHandling->fFormLift); + float upImpulseRight = -upRight * pFlyingHandling->fAttackLift * m_fTurnMass * CTimer::GetTimeStep(); + ApplyTurnForce(upImpulseRight * GetUp(), GetRight()); + + float upFwd = clamp(GetForward().z, -pFlyingHandling->fFormLift, pFlyingHandling->fFormLift); + float upImpulseFwd = -upFwd * pFlyingHandling->fAttackLift * m_fTurnMass * CTimer::GetTimeStep(); + ApplyTurnForce(upImpulseFwd * GetUp(), GetForward()); + }else{ + float upRight = GetRight().z < 0.0f ? -pFlyingHandling->fFormLift : pFlyingHandling->fFormLift; + float upImpulseRight = -upRight * pFlyingHandling->fAttackLift * m_fTurnMass * CTimer::GetTimeStep(); + ApplyTurnForce(upImpulseRight * GetUp(), GetRight()); + + float upFwd = GetForward().z < 0.0f ? -pFlyingHandling->fFormLift : pFlyingHandling->fFormLift; + float upImpulseFwd = -upFwd * pFlyingHandling->fAttackLift * m_fTurnMass * CTimer::GetTimeStep(); + ApplyTurnForce(upImpulseFwd * GetUp(), GetForward()); + } float fRoll, fPitch, fYaw; if (bCheat5) { - fPitch = CPad::GetPad(0)->GetCarGunUpDown() / 128.0f; - fRoll = -CPad::GetPad(0)->GetSteeringLeftRight() / 128.0f; - fYaw = CPad::GetPad(0)->GetCarGunLeftRight() / 128.0f; - } - else { fPitch = CPad::GetPad(0)->GetSteeringUpDown() / 128.0f; + fRoll = CPad::GetPad(0)->GetLookLeft(); + if (CPad::GetPad(0)->GetLookRight()) + fRoll = -1.0f; + fYaw = CPad::GetPad(0)->GetSteeringLeftRight() / 128.0f; + } else { + fPitch = CPad::GetPad(0)->GetSteeringUpDown() / 128.0f; + fRoll = -CPad::GetPad(0)->GetSteeringLeftRight() / 128.0f; fYaw = CPad::GetPad(0)->GetLookRight(); if (CPad::GetPad(0)->GetLookLeft()) fYaw = -1.0f; - fRoll = -CPad::GetPad(0)->GetSteeringLeftRight() / 128.0f; + if(Abs(CPad::GetPad(0)->GetCarGunLeftRight()) > 1.0f) + fYaw = CPad::GetPad(0)->GetCarGunLeftRight() / 128.0f; } + if(Abs(CPad::GetPad(0)->GetCarGunUpDown()) > 1.0f) + fPitch = -CPad::GetPad(0)->GetCarGunUpDown() / 128.0f; if (CPad::GetPad(0)->GetHorn()) { fYaw = 0.0f; - fPitch = clamp(10.0f * DotProduct(m_vecMoveSpeed, GetUp()), -200.0f, 1.3f); - fRoll = clamp(10.0f * DotProduct(m_vecMoveSpeed, GetRight()), -200.0f, 1.3f); + fPitch = clamp(pFlyingHandling->fPitchStab * DotProduct(m_vecMoveSpeed, GetForward()), -200.0f, 1.3f); + fRoll = clamp(pFlyingHandling->fRollStab * DotProduct(m_vecMoveSpeed, GetRight()), -200.0f, 1.3f); } - ApplyTurnForce(fPitch * GetUp() * fPitchVar * m_fTurnMass * CTimer::GetTimeStep(), GetForward()); - ApplyTurnForce(fRoll * GetUp() * fRollVar * m_fTurnMass * CTimer::GetTimeStep(), GetRight()); - ApplyTurnForce(fYaw * GetForward() * fYawVar * m_fTurnMass * CTimer::GetTimeStep(), GetRight()); + ApplyTurnForce(fPitch * GetUp() * pFlyingHandling->fPitch * m_fTurnMass * CTimer::GetTimeStep(), GetForward()); + ApplyTurnForce(fRoll * GetUp() * pFlyingHandling->fRoll * m_fTurnMass * CTimer::GetTimeStep(), GetRight()); - CVector vecResistance; - if (GetModelIndex() == MI_SPARROW) - vecResistance = vecHeliResistance; - else - vecResistance = vecRCHeliResistance; - float rX = Pow(vecResistance.x, CTimer::GetTimeStep()); - float rY = Pow(vecResistance.y, CTimer::GetTimeStep()); - float rZ = Pow(vecResistance.z, CTimer::GetTimeStep()); + float fSideSpeed = -DotProduct(GetMoveSpeed(), GetRight()); + float fSideSlipAccel = pFlyingHandling->fSideSlip * fSideSpeed * Abs(fSideSpeed); + ApplyMoveForce(m_fMass * GetRight() * fSideSlipAccel * CTimer::GetTimeStep()); + float fYawAccel = pFlyingHandling->fYawStab * fSideSpeed * Abs(fSideSpeed) + pFlyingHandling->fYaw * fYaw; + ApplyTurnForce(fYawAccel * GetRight() * m_fTurnMass * CTimer::GetTimeStep(), -GetForward()); + + ApplyTurnForce(fYaw * GetForward() * pFlyingHandling->fYaw * m_fTurnMass * CTimer::GetTimeStep(), GetRight()); + + float rX = Pow(pFlyingHandling->vecTurnRes.x, CTimer::GetTimeStep()); + float rY = Pow(pFlyingHandling->vecTurnRes.y, CTimer::GetTimeStep()); + float rZ = Pow(pFlyingHandling->vecTurnRes.z, CTimer::GetTimeStep()); CVector vecTurnSpeed = Multiply3x3(m_vecTurnSpeed, GetMatrix()); - float fResistanceMultiplier = Pow(1.0f / (fSpinSpeedRes * SQR(vecTurnSpeed.z) + 1.0f), CTimer::GetTimeStep()); + float fResistanceMultiplier = Pow(1.0f / (pFlyingHandling->vecSpeedRes.z * SQR(vecTurnSpeed.z) + 1.0f) * rZ, CTimer::GetTimeStep()); float fResistance = vecTurnSpeed.z * fResistanceMultiplier - vecTurnSpeed.z; vecTurnSpeed.x *= rX; vecTurnSpeed.y *= rY; - vecTurnSpeed.z *= rZ; + vecTurnSpeed.z *= fResistanceMultiplier; m_vecTurnSpeed = Multiply3x3(GetMatrix(), vecTurnSpeed); ApplyTurnForce(-GetRight() * fResistance * m_fTurnMass, GetForward() + Multiply3x3(GetMatrix(), m_vecCentreOfMass)); break; @@ -459,6 +492,228 @@ CVehicle::FlyingControl(eFlightModel flightModel) } } +static CColModel rotorColModel; +static CColSphere rotorColSphere; +float ROTOR_SEMI_THICKNESS = 0.05f; +float ROTOR_TURN_SPEED = 0.2f; +float ROTOR_DISGUARD_MULT = 0.3f; +float ROTOR_COL_ELASTICITY = 1.0f; +float ROTOR_COL_TURNMULT = -0.001f; +float ROTOR_DEFAULT_DAMAGE = 100.0f; + +bool +CVehicle::DoBladeCollision(CVector pos, CMatrix &matrix, int16 rotorType, float radius, float damageMult) +{ + CVector max(radius, radius, radius); + CVector min(-radius, -radius, -radius); + + switch(rotorType){ + case ROTOR_TOP: + case ROTOR_BOTTOM: + min.z = -ROTOR_SEMI_THICKNESS; + max.z = ROTOR_SEMI_THICKNESS; + break; + case ROTOR_FRONT: + case ROTOR_BACK: + min.y = -ROTOR_SEMI_THICKNESS; + max.y = ROTOR_SEMI_THICKNESS; + break; + case ROTOR_RIGHT: + case ROTOR_LEFT: + min.x = -ROTOR_SEMI_THICKNESS; + max.x = ROTOR_SEMI_THICKNESS; + break; + } + + min += pos; + max += pos; + rotorColModel.boundingBox.Set(min, max); + rotorColModel.boundingSphere.Set(radius, pos); + rotorColSphere.Set(radius, pos, 0, 0); + rotorColModel.spheres = &rotorColSphere; + rotorColModel.numSpheres = 1; + + pos = matrix * pos; + bool hadCollision; + int minX = CWorld::GetSectorIndexX(pos.x - radius); + if(minX <= 0) minX = 0; + + int minY = CWorld::GetSectorIndexY(pos.y - radius); + if(minY <= 0) minY = 0; + + int maxX = CWorld::GetSectorIndexX(pos.x + radius); +#ifdef FIX_BUGS + if(maxX >= NUMSECTORS_X) maxX = NUMSECTORS_X - 1; +#else + if(maxX >= NUMSECTORS_X) maxX = NUMSECTORS_X; +#endif + + int maxY = CWorld::GetSectorIndexY(pos.y + radius); +#ifdef FIX_BUGS + if(maxY >= NUMSECTORS_Y) maxY = NUMSECTORS_Y - 1; +#else + if(maxY >= NUMSECTORS_Y) maxY = NUMSECTORS_Y; +#endif + + CWorld::AdvanceCurrentScanCode(); + for(int curY = minY; curY <= maxY; curY++) { + for(int curX = minX; curX <= maxX; curX++) { + CSector *sector = CWorld::GetSector(curX, curY); + if(BladeColSectorList(sector->m_lists[ENTITYLIST_BUILDINGS], rotorColModel, matrix, rotorType, damageMult)) + hadCollision = true; + if(BladeColSectorList(sector->m_lists[ENTITYLIST_BUILDINGS_OVERLAP], rotorColModel, matrix, rotorType, damageMult)) + hadCollision = true; + if(BladeColSectorList(sector->m_lists[ENTITYLIST_VEHICLES], rotorColModel, matrix, rotorType, damageMult)) + hadCollision = true; + if(BladeColSectorList(sector->m_lists[ENTITYLIST_VEHICLES_OVERLAP], rotorColModel, matrix, rotorType, damageMult)) + hadCollision = true; + if(BladeColSectorList(sector->m_lists[ENTITYLIST_PEDS], rotorColModel, matrix, rotorType, 0.0f)) + hadCollision = true; + if(BladeColSectorList(sector->m_lists[ENTITYLIST_PEDS_OVERLAP], rotorColModel, matrix, rotorType, 0.0f)) + hadCollision = true; + if(BladeColSectorList(sector->m_lists[ENTITYLIST_OBJECTS], rotorColModel, matrix, rotorType, damageMult)) + hadCollision = true; + if(BladeColSectorList(sector->m_lists[ENTITYLIST_OBJECTS_OVERLAP], rotorColModel, matrix, rotorType, damageMult)) + hadCollision = true; + } + } + rotorColModel.spheres = nil; + rotorColModel.numSpheres = 0; + + return hadCollision; +} + +bool +CVehicle::BladeColSectorList(CPtrList &list, CColModel &rotorColModel, CMatrix &matrix, int16 rotorType, float damageMult) +{ + int i; + CVector axis; + CVector turnSpeed(0.0f, 0.0f, 0.0f); + switch(rotorType){ + case ROTOR_TOP: + turnSpeed.z = -ROTOR_TURN_SPEED; + axis = -matrix.GetUp(); + break; + case ROTOR_BOTTOM: + turnSpeed.z = ROTOR_TURN_SPEED; + axis = matrix.GetUp(); + break; + + case ROTOR_FRONT: + turnSpeed.y = -ROTOR_TURN_SPEED; + axis = -matrix.GetForward(); + break; + case ROTOR_BACK: + turnSpeed.y = ROTOR_TURN_SPEED; + axis = matrix.GetForward(); + break; + + case ROTOR_RIGHT: + turnSpeed.x = -ROTOR_TURN_SPEED; + axis = -matrix.GetRight(); + break; + case ROTOR_LEFT: + turnSpeed.x = ROTOR_TURN_SPEED; + axis = matrix.GetRight(); + break; + } + turnSpeed = Multiply3x3(matrix, turnSpeed); + CVector center = rotorColModel.boundingSphere.center; + center = matrix*center; + + for(CPtrNode *node = list.first; node; node = node->next) { + CEntity *entity = (CEntity *)node->item; + if(entity == (CEntity*)this || + !entity->bUsesCollision || + entity->m_scanCode == CWorld::GetCurrentScanCode()) + continue; + + entity->m_scanCode = CWorld::GetCurrentScanCode(); + + int numCollisions; + CColModel *entityCol; + if(entity->IsPed()) + entityCol = ((CPedModelInfo*)CModelInfo::GetModelInfo(entity->GetModelIndex()))->AnimatePedColModelSkinned(entity->GetClump()); + else + entityCol = CModelInfo::GetModelInfo(entity->GetModelIndex())->GetColModel(); + if(entityCol) + numCollisions = CCollision::ProcessColModels(matrix, rotorColModel, entity->GetMatrix(), *entityCol, + CWorld::m_aTempColPts, nil, nil); + else + numCollisions = 0; + + if(numCollisions > 0 && entity->IsPed()){ + CPed *ped = (CPed*)entity; + CVector2D dirToRotor = GetPosition() - entity->GetPosition(); + dirToRotor.Normalise(); + int localDir = ped->GetLocalDirection(dirToRotor); + if(ped->m_attachedTo == nil){ + ped->bIsStanding = false; + ped->ApplyMoveForce(-5.0f*dirToRotor.x, -5.0f*dirToRotor.y, 5.0f); + } + ped->InflictDamage(this, WEAPONTYPE_RUNOVERBYCAR, 1000.0f, PEDPIECE_TORSO, localDir); + + if(CGame::nastyGame && ped->GetIsOnScreen()){ + for(i = 0; i < 16; i++) + CParticle::AddParticle(PARTICLE_BLOOD_SMALL, ped->GetPosition(), CVector(dirToRotor.x, dirToRotor.y, 1.0f) * 0.01f); + CParticle::AddParticle(PARTICLE_TEST, ped->GetPosition(), CVector(0.0f, 0.0f, 0.02f), nil, 0.1f); + CParticle::AddParticle(PARTICLE_TEST, ped->GetPosition()+CVector(0.0f, 0.0f, 0.2f), CVector(0.0f, 0.0f, -0.01f), nil, 0.1f); + } + }else if(numCollisions > 0 && entity->GetModelIndex() != MI_MISSILE){ + float impulse = 0.0f; + bool hadCollision = false; + float savedElasticity = m_fElasticity; + m_fElasticity = ROTOR_COL_ELASTICITY; + + for(i = 0; i < numCollisions; i++){ + CVector colpos = CWorld::m_aTempColPts[i].point; + CVector localColpos = colpos - center; + float axisDir = DotProduct(axis, localColpos); + float colDir = DotProduct(CWorld::m_aTempColPts[i].normal, localColpos); + if(2.0f*ROTOR_SEMI_THICKNESS < Abs(axisDir) && + ROTOR_DISGUARD_MULT*Abs(colDir) < Abs(axisDir)) + continue; + + colpos -= axisDir*axis; // get rid of axis component + + CVector tangentSpeed = CrossProduct(turnSpeed, colpos - center); + + // Particles + for(int j = 0; j < 4; j++){ + CParticle::AddParticle(PARTICLE_SPARK_SMALL, colpos, (tangentSpeed+m_vecMoveSpeed)/2.0f); + CParticle::AddParticle(PARTICLE_SPARK, colpos, 0.1f*CWorld::m_aTempColPts[i].normal); + } + + // Apply Collision + if(IsCar()){ + CAutomobile *heli = (CAutomobile*)this; + if(heli->m_fRotorSpeed > 0.15f){ + ApplyCollision(CWorld::m_aTempColPts[i], impulse); + ApplyTurnForce(m_fTurnMass*ROTOR_COL_TURNMULT*tangentSpeed, colpos - center); + heli->m_fRotorSpeed = 0.15f; + }else if(heli->m_fRotorSpeed < 0.075f && heli->m_fRotorSpeed > 0.0f) + heli->m_fRotorSpeed *= -1.0f; + } + + float damageImpulse = damageMult * Max(impulse, ROTOR_DEFAULT_DAMAGE*m_fMass/3000.0f); + if(damageImpulse > m_fDamageImpulse) + SetDamagedPieceRecord(0, damageImpulse, entity, CWorld::m_aTempColPts[i].normal); + + hadCollision = true; + } + + if(hadCollision && !entity->IsPed()) + DMAudio.ReportCollision(this, entity, SURFACE_CAR_PANEL, SURFACE_TARMAC, 50.0f, 0.09f); + m_fElasticity = savedElasticity; + } + } + return false; +} + + +float fBurstSpeedMax = 0.3f; +float fBurstTyreMod = 0.13f; + void CVehicle::ProcessWheel(CVector &wheelFwd, CVector &wheelRight, CVector &wheelContactSpeed, CVector &wheelContactPoint, int32 wheelsOnGround, float thrust, float brake, float adhesion, int8 wheelId, float *wheelSpeed, tWheelState *wheelState, uint16 wheelStatus) @@ -468,6 +723,10 @@ CVehicle::ProcessWheel(CVector &wheelFwd, CVector &wheelRight, CVector &wheelCon static bool bBraking; static bool bDriving; +#ifdef FIX_BUGS + bAlreadySkidding = false; +#endif + // how much force we want to apply in these axes float fwd = 0.0f; float right = 0.0f; @@ -492,10 +751,15 @@ CVehicle::ProcessWheel(CVector &wheelFwd, CVector &wheelRight, CVector &wheelCon if(contactSpeedRight != 0.0f){ // exert opposing force right = -contactSpeedRight/wheelsOnGround; +#ifdef FIX_BUGS + // contactSpeedRight is independent of framerate but right has timestep as a factor + // so we probably have to fix this + right *= CTimer::GetTimeStepFix(); +#endif if(wheelStatus == WHEEL_STATUS_BURST){ - float fwdspeed = Min(contactSpeedFwd, 0.3f); - right += fwdspeed * CGeneral::GetRandomNumberInRange(-0.1f, 0.1f); + float fwdspeed = Min(contactSpeedFwd, fBurstSpeedMax); + right += fwdspeed * CGeneral::GetRandomNumberInRange(-fBurstTyreMod, fBurstTyreMod); } } @@ -512,13 +776,25 @@ CVehicle::ProcessWheel(CVector &wheelFwd, CVector &wheelRight, CVector &wheelCon } }else if(contactSpeedFwd != 0.0f){ fwd = -contactSpeedFwd/wheelsOnGround; +#ifdef FIX_BUGS + // contactSpeedFwd is independent of framerate but fwd has timestep as a factor + // so we probably have to fix this + fwd *= CTimer::GetTimeStepFix(); +#endif if(!bBraking){ if(m_fGasPedal < 0.01f){ - if(GetModelIndex() == MI_RCBANDIT) - brake = 0.2f * mod_HandlingManager.field_4 / m_fMass; + if(IsBike()) + brake = 0.6f * mod_HandlingManager.fWheelFriction / (pHandling->fMass + 200.0f); + else if(pHandling->fMass < 500.0f) + brake = mod_HandlingManager.fWheelFriction / m_fMass; + else if(GetModelIndex() == MI_RCBANDIT) + brake = 0.2f * mod_HandlingManager.fWheelFriction / m_fMass; else - brake = mod_HandlingManager.field_4 / m_fMass; + brake = mod_HandlingManager.fWheelFriction / m_fMass; +#ifdef FIX_BUGS + brake *= CTimer::GetTimeStepFix(); +#endif } } @@ -536,7 +812,8 @@ CVehicle::ProcessWheel(CVector &wheelFwd, CVector &wheelRight, CVector &wheelCon } } - if(sq(adhesion) < sq(right) + sq(fwd)){ + float speedSq = sq(right) + sq(fwd); + if(sq(adhesion) < speedSq){ if(*wheelState != WHEEL_STATE_FIXED){ if(bDriving && contactSpeedFwd < 0.2f) *wheelState = WHEEL_STATE_SPINNING; @@ -544,22 +821,205 @@ CVehicle::ProcessWheel(CVector &wheelFwd, CVector &wheelRight, CVector &wheelCon *wheelState = WHEEL_STATE_SKIDDING; } - float l = Sqrt(sq(right) + sq(fwd)); + float l = Sqrt(speedSq); float tractionLoss = bAlreadySkidding ? 1.0f : pHandling->fTractionLoss; right *= adhesion * tractionLoss / l; fwd *= adhesion * tractionLoss / l; } + if(fwd != 0.0f || right != 0.0f){ + CVector totalSpeed = fwd*wheelFwd + right*wheelRight; + + CVector turnDirection = totalSpeed; + bool separateTurnForce = false; // BUG: not initialized on PC + if(pHandling->fSuspensionAntidiveMultiplier > 0.0f){ + if(bBraking){ + separateTurnForce = true; + turnDirection = totalSpeed - pHandling->fSuspensionAntidiveMultiplier*fwd*wheelFwd; + }else if(bDriving){ + separateTurnForce = true; + turnDirection = totalSpeed - 0.5f*pHandling->fSuspensionAntidiveMultiplier*fwd*wheelFwd; + } + } + + CVector direction = totalSpeed; + + float speed = totalSpeed.Magnitude(); + float turnSpeed; + if(separateTurnForce) + turnSpeed = turnDirection.Magnitude(); + else + turnSpeed = speed; + direction.Normalise(); + if(separateTurnForce) + turnDirection.Normalise(); + else + turnDirection = direction; + + float impulse = speed*m_fMass; + float turnImpulse = turnSpeed*GetMass(wheelContactPoint, turnDirection); + + ApplyMoveForce(impulse * direction); + ApplyTurnForce(turnImpulse * direction, wheelContactPoint); + } +} + +float fBurstBikeSpeedMax = 0.12f; +float fBurstBikeTyreMod = 0.05f; +float fTweakBikeWheelTurnForce = 2.0f; + +void +CVehicle::ProcessBikeWheel(CVector &wheelFwd, CVector &wheelRight, CVector &wheelContactSpeed, CVector &wheelContactPoint, + int32 wheelsOnGround, float thrust, float brake, float adhesion, float unk, int8 wheelId, float *wheelSpeed, tWheelState *wheelState, eBikeWheelSpecial special, uint16 wheelStatus) +{ + // BUG: using statics here is probably a bad idea + static bool bAlreadySkidding = false; // this is never reset + static bool bBraking; + static bool bDriving; + static bool bReversing; + +#ifdef FIX_BUGS + bAlreadySkidding = false; +#endif + + // how much force we want to apply in these axes + float fwd = 0.0f; + float right = 0.0f; + + bBraking = brake != 0.0f; + if(bBraking) + thrust = 0.0f; + bDriving = thrust != 0.0f; + bReversing = thrust < 0.0f; + + float contactSpeedFwd = DotProduct(wheelContactSpeed, wheelFwd); + float contactSpeedRight; + + if(*wheelState != WHEEL_STATE_NORMAL) + bAlreadySkidding = true; + *wheelState = WHEEL_STATE_NORMAL; + + adhesion *= CTimer::GetTimeStep(); + if(bAlreadySkidding) + adhesion *= pHandling->fTractionLoss; + + if(special == BIKE_WHEEL_2 || special == BIKE_WHEEL_3) + contactSpeedRight = 0.0f; + else + contactSpeedRight = DotProduct(wheelContactSpeed, wheelRight); + + // moving sideways + if(contactSpeedRight != 0.0f){ + // exert opposing force + right = -contactSpeedRight/wheelsOnGround; +#ifdef FIX_BUGS + // contactSpeedRight is independent of framerate but right has timestep as a factor + // so we probably have to fix this + right *= CTimer::GetTimeStepFix(); +#endif + + if(wheelStatus == WHEEL_STATUS_BURST){ + float fwdspeed = Min(contactSpeedFwd, fBurstBikeSpeedMax); + right += fwdspeed * CGeneral::GetRandomNumberInRange(-fBurstBikeTyreMod, fBurstBikeTyreMod); + } + } + + if(bDriving){ + fwd = thrust; + + // limit sideways force (why?) + if(right > 0.0f){ + if(right > adhesion) + right = adhesion; + }else{ + if(right < -adhesion) + right = -adhesion; + } + }else if(contactSpeedFwd != 0.0f){ + fwd = -contactSpeedFwd/wheelsOnGround; +#ifdef FIX_BUGS + // contactSpeedFwd is independent of framerate but fwd has timestep as a factor + // so we probably have to fix this + fwd *= CTimer::GetTimeStepFix(); +#endif + + if(!bBraking){ + if(m_fGasPedal < 0.01f){ + if(IsBike()) + brake = 0.6f * mod_HandlingManager.fWheelFriction / (pHandling->fMass + 200.0f); + else if(pHandling->fMass < 500.0f) + brake = mod_HandlingManager.fWheelFriction / m_fMass; + else if(GetModelIndex() == MI_RCBANDIT) + brake = 0.2f * mod_HandlingManager.fWheelFriction / m_fMass; + else + brake = mod_HandlingManager.fWheelFriction / m_fMass; +#ifdef FIX_BUGS + brake *= CTimer::GetTimeStepFix(); +#endif + } + } + + if(brake > adhesion){ + if(Abs(contactSpeedFwd) > 0.005f) + *wheelState = WHEEL_STATE_FIXED; + }else { + if(fwd > 0.0f){ + if(fwd > brake) + fwd = brake; + }else{ + if(fwd < -brake) + fwd = -brake; + } + } + } + + float speedSq = sq(right) + sq(fwd); + if(sq(adhesion) < speedSq){ + if(*wheelState != WHEEL_STATE_FIXED){ + if(bDriving && contactSpeedFwd < 0.2f) + *wheelState = WHEEL_STATE_SPINNING; + else + *wheelState = WHEEL_STATE_SKIDDING; + } + + float l = Sqrt(speedSq); + float tractionLoss = bAlreadySkidding ? 1.0f : pHandling->fTractionLoss; + right *= adhesion * tractionLoss / l; + fwd *= adhesion * tractionLoss / l; + + if(unk < 1.0f) + right *= unk; + }else if(unk < 1.0f){ + if(!bAlreadySkidding) + unk *= pHandling->fTractionLoss; + if(sq(adhesion*unk) < speedSq){ + float l = Sqrt(speedSq); + right *= adhesion * unk / l; + } + } + if(fwd != 0.0f || right != 0.0f){ CVector direction = fwd*wheelFwd + right*wheelRight; + float speed = direction.Magnitude(); direction.Normalise(); float impulse = speed*m_fMass; float turnImpulse = speed*GetMass(wheelContactPoint, direction); + CVector vTurnImpulse = turnImpulse * direction; + float turnRight = DotProduct(vTurnImpulse, GetRight()); ApplyMoveForce(impulse * direction); - ApplyTurnForce(turnImpulse * direction, wheelContactPoint); + + float contactRight = DotProduct(wheelContactPoint, GetRight()); + float contactFwd = DotProduct(wheelContactPoint, GetForward()); + + if(wheelId != CARWHEEL_REAR_LEFT || + !bBraking && !bReversing) + ApplyTurnForce((vTurnImpulse - turnRight*GetRight()) * fTweakBikeWheelTurnForce, + wheelContactPoint - contactRight*GetRight()); + + ApplyTurnForce(turnRight*GetRight(), contactFwd*GetForward()); } } @@ -581,38 +1041,81 @@ CVehicle::ProcessWheelRotation(tWheelState state, const CVector &fwd, const CVec return angularVelocity * CTimer::GetTimeStep(); } +int +CVehicle::FindTyreNearestPoint(float x, float y) +{ + CVector pos = CVector(x - GetPosition().x, y - GetPosition().y, 0.0f); + float fwd = DotProduct(GetForward(), pos); + float right = DotProduct(GetRight(), pos); + + int piece; + if(IsBike()){ + piece = fwd > 0.0f ? CAR_PIECE_WHEEL_LF : CAR_PIECE_WHEEL_LR; + }else{ + piece = fwd > 0.0f ? + right > 0.0f ? CAR_PIECE_WHEEL_RF : CAR_PIECE_WHEEL_LF : + right > 0.0f ? CAR_PIECE_WHEEL_RR : CAR_PIECE_WHEEL_LR; + } + return piece - CAR_PIECE_WHEEL_LF; +} + void -CVehicle::InflictDamage(CEntity* damagedBy, eWeaponType weaponType, float damage) +CVehicle::InflictDamage(CEntity *damagedBy, eWeaponType weaponType, float damage, CVector pos) { if (!bCanBeDamaged) return; - if (bOnlyDamagedByPlayer && (damagedBy != FindPlayerPed() && damagedBy != FindPlayerVehicle())) + if(GetStatus() == STATUS_PLAYER && CStats::GetPercentageProgress() >= 100.0f) + damage *= 0.5f; + if (GetStatus() != STATUS_PLAYER && bOnlyDamagedByPlayer && (damagedBy != FindPlayerPed() && damagedBy != FindPlayerVehicle())) return; + + if(damage > 10.0f && (damagedBy == FindPlayerPed() || damagedBy == FindPlayerVehicle()) && GetStatus() != STATUS_WRECKED){ + CWorld::Players[CWorld::PlayerInFocus].m_nHavocLevel += 2; + CWorld::Players[CWorld::PlayerInFocus].m_fMediaAttention += 1.0f; + CStats::PropertyDestroyed += CGeneral::GetRandomNumberInRange(5, 25); + } + bool bFrightensDriver = false; switch (weaponType) { case WEAPONTYPE_UNARMED: + case WEAPONTYPE_BRASSKNUCKLE: + case WEAPONTYPE_SCREWDRIVER: + case WEAPONTYPE_GOLFCLUB: + case WEAPONTYPE_NIGHTSTICK: + case WEAPONTYPE_KNIFE: case WEAPONTYPE_BASEBALLBAT: + case WEAPONTYPE_HAMMER: + case WEAPONTYPE_CLEAVER: + case WEAPONTYPE_MACHETE: + case WEAPONTYPE_KATANA: + case WEAPONTYPE_CHAINSAW: if (bMeleeProof) return; break; case WEAPONTYPE_COLT45: - case WEAPONTYPE_UZI: + case WEAPONTYPE_PYTHON: + case WEAPONTYPE_SHOTGUN: + case WEAPONTYPE_SPAS12_SHOTGUN: + case WEAPONTYPE_STUBBY_SHOTGUN: case WEAPONTYPE_TEC9: + case WEAPONTYPE_UZI: case WEAPONTYPE_SILENCED_INGRAM: case WEAPONTYPE_MP5: - case WEAPONTYPE_SHOTGUN: - case WEAPONTYPE_AK47: - case WEAPONTYPE_M16: + case WEAPONTYPE_M4: + case WEAPONTYPE_RUGER: case WEAPONTYPE_SNIPERRIFLE: + case WEAPONTYPE_LASERSCOPE: + case WEAPONTYPE_M60: + case WEAPONTYPE_MINIGUN: case WEAPONTYPE_HELICANNON: case WEAPONTYPE_UZI_DRIVEBY: if (bBulletProof) return; bFrightensDriver = true; break; - case WEAPONTYPE_ROCKETLAUNCHER: - case WEAPONTYPE_MOLOTOV: case WEAPONTYPE_GRENADE: + case WEAPONTYPE_MOLOTOV: + case WEAPONTYPE_ROCKET: case WEAPONTYPE_EXPLOSION: if (bExplosionProof) return; @@ -629,6 +1132,52 @@ CVehicle::InflictDamage(CEntity* damagedBy, eWeaponType weaponType, float damage default: break; } + + if(bFrightensDriver && GetStatus() == STATUS_PLAYER && m_fHealth < 250.0f) + return; + + // Pop tires + if(damagedBy && damagedBy->IsPed() && (IsCar() || IsBike())){ + int accuracy = 0; + switch(weaponType){ + case WEAPONTYPE_COLT45: + accuracy = 10; + break; + case WEAPONTYPE_PYTHON: + if(!((CPed*)damagedBy)->IsPlayer()) + accuracy = 64; + break; + case WEAPONTYPE_SHOTGUN: + case WEAPONTYPE_STUBBY_SHOTGUN: + case WEAPONTYPE_M60: + case WEAPONTYPE_HELICANNON: + accuracy = 25; + break; + case WEAPONTYPE_TEC9: + case WEAPONTYPE_UZI: + case WEAPONTYPE_SILENCED_INGRAM: + case WEAPONTYPE_MP5: + case WEAPONTYPE_UZI_DRIVEBY: + accuracy = 15; + break; + case WEAPONTYPE_M4: + case WEAPONTYPE_RUGER: + if(!((CPed*)damagedBy)->IsPlayer()) + accuracy = 15; + break; + } + + if(((CPed*)damagedBy)->IsPlayer() && (CCamera::m_bUseMouse3rdPerson || TheCamera.Using1stPersonWeaponMode())) + accuracy = 0; + + if(accuracy != 0 && !bTyresDontBurst && (CGeneral::GetRandomNumber()&0x7F) < accuracy){ + if(IsBike()) + BurstTyre(FindTyreNearestPoint(pos.x, pos.y) + CAR_PIECE_WHEEL_LF, false); + else if(GetVehicleAppearance() == VEHICLE_APPEARANCE_CAR) + BurstTyre(FindTyreNearestPoint(pos.x, pos.y) + CAR_PIECE_WHEEL_LF, true); + } + } + if (m_fHealth > 0.0f) { if (VehicleCreatedBy == RANDOM_VEHICLE && pDriver && (GetStatus() == STATUS_SIMPLE || GetStatus() == STATUS_PHYSICS) && @@ -641,24 +1190,43 @@ CVehicle::InflictDamage(CEntity* damagedBy, eWeaponType weaponType, float damage } } m_nLastWeaponDamage = weaponType; + m_pLastDamageEntity = damagedBy; float oldHealth = m_fHealth; if (m_fHealth > damage) { m_fHealth -= damage; - if (VehicleCreatedBy == RANDOM_VEHICLE && - (m_fHealth < DAMAGE_HEALTH_TO_FLEE_ALWAYS || - bFrightensDriver && m_randomSeed > DAMAGE_FLEE_ON_FOOT_PROBABILITY_VALUE)) { + if (VehicleCreatedBy == RANDOM_VEHICLE && !IsBoat()){ switch (GetStatus()) { case STATUS_SIMPLE: case STATUS_PHYSICS: - if (pDriver) { - SetStatus(STATUS_ABANDONED); - pDriver->bFleeAfterExitingCar = true; - pDriver->SetObjective(OBJECTIVE_LEAVE_VEHICLE, this); - } - for (int i = 0; i < m_nNumMaxPassengers; i++) { - if (pPassengers[i]) { - pPassengers[i]->bFleeAfterExitingCar = true; - pPassengers[i]->SetObjective(OBJECTIVE_LEAVE_VEHICLE, this); + if(AutoPilot.m_nDrivingStyle == DRIVINGSTYLE_PLOUGH_THROUGH || + CGeneral::GetRandomNumberInRange(0.0f, 1.0f) > 0.5f && AutoPilot.m_nCarMission == MISSION_CRUISE){ + // Drive away like a maniac + if(pDriver && pDriver->m_objective != OBJECTIVE_LEAVE_VEHICLE){ + if(AutoPilot.m_nDrivingStyle != DRIVINGSTYLE_PLOUGH_THROUGH) + AutoPilot.m_nCruiseSpeed *= 1.5f; + AutoPilot.m_nDrivingStyle = DRIVINGSTYLE_PLOUGH_THROUGH; + } + }else{ + // Leave vehicle + if (pDriver && pDriver->CharCreatedBy != MISSION_CHAR) { + SetStatus(STATUS_ABANDONED); + pDriver->bFleeAfterExitingCar = true; + pDriver->SetObjective(OBJECTIVE_LEAVE_VEHICLE, this); +// TODO(MIAMI): +// pDriver->Say(120); + } + int time = 200; + for (int i = 0; i < m_nNumMaxPassengers; i++) { + if (pPassengers[i] && + pPassengers[i]->m_objective != OBJECTIVE_LEAVE_VEHICLE && + pPassengers[i]->CharCreatedBy != MISSION_CHAR) { + pPassengers[i]->bFleeAfterExitingCar = true; + pPassengers[i]->SetObjective(OBJECTIVE_LEAVE_VEHICLE, this); + pPassengers[i]->m_objectiveTimer = CTimer::GetTimeInMilliseconds() + time; +// TODO(MIAMI): +// pPassengers[i]->Say(120); + time += 200; + } } } break; @@ -666,7 +1234,7 @@ CVehicle::InflictDamage(CEntity* damagedBy, eWeaponType weaponType, float damage break; } } - if (oldHealth > DAMAGE_HEALTH_TO_CATCH_FIRE && m_fHealth < DAMAGE_HEALTH_TO_CATCH_FIRE) { + if (oldHealth >= DAMAGE_HEALTH_TO_CATCH_FIRE && m_fHealth < DAMAGE_HEALTH_TO_CATCH_FIRE) { if (IsCar()) { CAutomobile* pThisCar = (CAutomobile*)this; pThisCar->Damage.SetEngineStatus(ENGINE_STATUS_ON_FIRE); @@ -700,11 +1268,13 @@ CVehicle::InflictDamage(CEntity* damagedBy, eWeaponType weaponType, float damage void CVehicle::DoFixedMachineGuns(void) { - if(CPad::GetPad(0)->GetCarGunFired() && !bGunSwitchedOff){ - FireFixedMachineGuns(); - }else{ - if(CTimer::GetTimeInMilliseconds() > m_nGunFiringTime + 1400) - m_nAmmoInClip = 20; + if(TheCamera.Cams[TheCamera.ActiveCam].DirectionWasLooking == LOOKING_FORWARD){ + if(CPad::GetPad(0)->GetCarGunFired() && !bGunSwitchedOff){ + FireFixedMachineGuns(); + }else{ + if(CTimer::GetTimeInMilliseconds() > m_nGunFiringTime + 1400) + m_nAmmoInClip = 20; + } } } @@ -752,10 +1322,44 @@ CVehicle::FireFixedMachineGuns(void) } } +void +CVehicle::ActivateBomb(void) +{ + if(m_bombType == CARBOMB_TIMED){ + m_bombType = CARBOMB_TIMEDACTIVE; + m_nBombTimer = 7000; + m_pBlowUpEntity = FindPlayerPed(); + CGarages::TriggerMessage("GA_12", -1, 3000, -1); + DMAudio.PlayOneShot(m_audioEntityId, SOUND_BOMB_TIMED_ACTIVATED, 1.0f); + }else if(m_bombType == CARBOMB_ONIGNITION){ + m_bombType = CARBOMB_ONIGNITIONACTIVE; + CGarages::TriggerMessage("GA_12", -1, 3000, -1); + DMAudio.PlayOneShot(m_audioEntityId, SOUND_BOMB_ONIGNITION_ACTIVATED, 1.0f); + } +} + +void +CVehicle::ActivateBombWhenEntered(void) +{ + if(pDriver){ + if(!bDriverLastFrame && m_bombType == CARBOMB_ONIGNITIONACTIVE){ + // If someone enters the car and there is a bomb, detonate + m_nBombTimer = 1000; + m_pBlowUpEntity = m_pBombRigger; + if(m_pBlowUpEntity) + m_pBlowUpEntity->RegisterReference((CEntity**)&m_pBlowUpEntity); + DMAudio.PlayOneShot(m_audioEntityId, SOUND_BOMB_TICK, 1.0f); + } + bDriverLastFrame = true; + }else + bDriverLastFrame = false; +} + void CVehicle::ExtinguishCarFire(void) { - m_fHealth = Max(m_fHealth, 300.0f); + if(GetStatus() != STATUS_WRECKED) + m_fHealth = Max(m_fHealth, 300.0f); if(m_pCarFire) m_pCarFire->Extinguish(); if(IsCar()){ @@ -825,6 +1429,69 @@ CVehicle::ShufflePassengersToMakeSpace(void) return false; } +void +CVehicle::MakeNonDraggedPedsLeaveVehicle(CPed *ped1, CPed *ped2, CPlayerPed *&player, CCopPed *&cop) +{ + int i; + player = nil; + cop = nil; + + if(ped1->IsPlayer() && ped2->m_nPedType == PEDTYPE_COP && + ((CPlayerPed*)ped1)->m_pWanted->m_nWantedLevel > 0 && + ped2->m_pedInObjective == ped1){ + player = (CPlayerPed*)ped1; + cop = (CCopPed*)ped2; + return; + } + + bool ped1IsDriver = ped1 == pDriver; + + // Just what the hell is this weird code? + CPed *peds[9]; + CPed *peds2[9]; + int numPeds = 0; + int numPeds2 = 0; + for(i = 0; i < m_nNumMaxPassengers; i++){ + CPed *p = pPassengers[i]; + if(p && p != ped1 && !p->bStayInCarOnJack){ + peds[numPeds++] = p; + // uhh what? + if(i < 1 && !ped1IsDriver) + continue; + peds2[numPeds2++] = p; + } + } + + // So we're copying this array for no reason... + CPed *peds3[9]; + int numPeds3 = 0; + for(i = 0; i < numPeds; i++){ + if(peds[i]->IsPlayer() && ped2->m_nPedType == PEDTYPE_COP && + ((CPlayerPed*)peds[i])->m_pWanted->m_nWantedLevel > 0 && + ped2->m_pedInObjective == peds[i]){ + player = (CPlayerPed*)peds[i]; + cop = (CCopPed*)ped2; + return; + } + peds3[numPeds3++] = peds[i]; + } + + int time = 1800; + for(i = 0; i < numPeds3; i++){ + peds3[i]->m_leaveCarTimer = CTimer::GetTimeInMilliseconds() + time; + peds3[i]->SetObjective(OBJECTIVE_LEAVE_VEHICLE, this); + time += CGeneral::GetRandomNumberInRange(300.0f, 600.0f); + } + + if(IsCar() && numPeds2 > 0 && CGeneral::GetRandomTrueFalse()) + for(i = 0; i < numPeds2; i++) + if(peds2[i]->IsFemale() || CGeneral::GetRandomTrueFalse()){ + peds2[i]->m_leaveCarTimer = CTimer::GetTimeInMilliseconds() + 10000; + peds2[i]->b156_8 = true; + peds2[i]->bFleeAfterExitingCar = true; + } +} + void CVehicle::ProcessDelayedExplosion(void) { @@ -844,8 +1511,6 @@ CVehicle::ProcessDelayedExplosion(void) if (m_nBombTimer != 0) return; - if(FindPlayerVehicle() != this && m_pBlowUpEntity == FindPlayerPed()) - CWorld::Players[CWorld::PlayerInFocus].AwardMoneyForExplosion(this); BlowUpCar(m_pBlowUpEntity); } @@ -853,12 +1518,13 @@ bool CVehicle::IsLawEnforcementVehicle(void) { switch(GetModelIndex()){ - case MI_FBICAR: case MI_POLICE: case MI_ENFORCER: case MI_PREDATOR: case MI_RHINO: case MI_BARRACKS: + case MI_FBIRANCH: + case MI_VICECHEE: return true; default: return false; @@ -876,6 +1542,8 @@ CVehicle::UsesSiren(uint32 id) case MI_POLICE: case MI_ENFORCER: case MI_PREDATOR: + case MI_FBIRANCH: + case MI_VICECHEE: return true; default: return false; @@ -964,19 +1632,27 @@ CVehicle::CanPedOpenLocks(CPed *ped) { if(m_nDoorLock == CARLOCK_LOCKED || m_nDoorLock == CARLOCK_LOCKED_INITIALLY || - m_nDoorLock == CARLOCK_LOCKED_PLAYER_INSIDE) + m_nDoorLock == CARLOCK_LOCKED_PLAYER_INSIDE || + m_nDoorLock == CARLOCK_SKIP_SHUT_DOORS) return false; if(ped->IsPlayer() && m_nDoorLock == CARLOCK_LOCKOUT_PLAYER_ONLY) return false; return true; } +bool +CVehicle::CanDoorsBeDamaged(void) +{ + return m_nDoorLock == CARLOCK_NOT_USED || + m_nDoorLock == CARLOCK_UNLOCKED || + m_nDoorLock == CARLOCK_SKIP_SHUT_DOORS; +} + bool CVehicle::CanPedEnterCar(void) { - CVector up = GetUp(); // can't enter when car is on side - if(up.z > 0.1f || up.z < -0.1f){ + if(IsBike() || GetUp().z > 0.1f || GetUp().z < -0.1f){ // also when car is moving too fast if(m_vecMoveSpeed.MagnitudeSqr() > sq(0.2f)) return false; @@ -988,16 +1664,14 @@ CVehicle::CanPedEnterCar(void) } bool -CVehicle::CanPedExitCar(void) +CVehicle::CanPedExitCar(bool jumpExit) { CVector up = GetUp(); if(up.z > 0.1f || up.z < -0.1f){ -#ifdef VC_PED_PORTS if (IsBoat()) return true; -#endif // can't exit when car is moving too fast - if(m_vecMoveSpeed.MagnitudeSqr() > 0.005f) + if(m_vecMoveSpeed.MagnitudeSqr() > 0.005f && !jumpExit) return false; // if car is slow enough, check turn speed if(Abs(m_vecTurnSpeed.x) > 0.01f || @@ -1020,6 +1694,14 @@ CVehicle::CanPedExitCar(void) } } +bool +CVehicle::CanPedJumpOffBike(void) +{ + if(pPassengers[0]) + return false; + return m_vecMoveSpeed.MagnitudeSqr() < 0.07f ? false : true; +} + void CVehicle::ChangeLawEnforcerState(uint8 enable) { @@ -1044,7 +1726,7 @@ CVehicle::SetUpDriver(void) if(VehicleCreatedBy != RANDOM_VEHICLE) return nil; - pDriver = CPopulation::AddPedInCar(this, false); + pDriver = CPopulation::AddPedInCar(this, true); pDriver->m_pMyVehicle = this; pDriver->m_pMyVehicle->RegisterReference((CEntity**)&pDriver->m_pMyVehicle); pDriver->bInVehicle = true; @@ -1057,15 +1739,31 @@ CVehicle::SetUpDriver(void) CPed* CVehicle::SetupPassenger(int n) { + int i; + if(pPassengers[n]) return pPassengers[n]; - pPassengers[n] = CPopulation::AddPedInCar(this, true); - pPassengers[n]->m_pMyVehicle = this; - pPassengers[n]->m_pMyVehicle->RegisterReference((CEntity**)&pPassengers[n]->m_pMyVehicle); - pPassengers[n]->bInVehicle = true; - pPassengers[n]->SetPedState(PED_DRIVING); - if(bIsBus) + if((IsTaxi() || IsLimo()) && n == 0) + pPassengers[0] = nil; + else{ + CPed *passenger = CPopulation::AddPedInCar(this, false); + pPassengers[n] = passenger; + passenger->m_pMyVehicle = this; + passenger->m_pMyVehicle->RegisterReference((CEntity**)&pPassengers[n]->m_pMyVehicle); + passenger->bInVehicle = true; + passenger->SetPedState(PED_DRIVING); + + if(passenger->m_nPedType == PEDTYPE_CIVMALE || passenger->m_nPedType == PEDTYPE_CIVFEMALE) + for(i = 0; i < n; i++) + if(pPassengers[i] && pPassengers[n] && + (pPassengers[i]->m_nPedType == PEDTYPE_CIVMALE || pPassengers[i]->m_nPedType == PEDTYPE_CIVFEMALE) && + passenger->GetModelIndex() == pPassengers[i]->GetModelIndex()){ + pPassengers[n] = nil; + CPopulation::RemovePed(passenger); + } + } + if(bIsBus && pPassengers[n]) pPassengers[n]->bRenderPedInCar = false; ++m_nNumPassengers; return pPassengers[n]; @@ -1078,24 +1776,42 @@ CVehicle::SetDriver(CPed *driver) pDriver->RegisterReference((CEntity**)&pDriver); if(bFreebies && driver == FindPlayerPed()){ - if(GetModelIndex() == MI_AMBULAN) - FindPlayerPed()->m_fHealth = Min(FindPlayerPed()->m_fHealth + 20.0f, 100.0f); - else if(GetModelIndex() == MI_TAXI) - CWorld::Players[CWorld::PlayerInFocus].m_nMoney += 25; - else if (GetModelIndex() == MI_POLICE) { - CStreaming::RequestModel(WEAPONTYPE_SHOTGUN, STREAMFLAGS_DONT_REMOVE); - driver->GiveWeapon(WEAPONTYPE_SHOTGUN, 5); - } else if (GetModelIndex() == MI_ENFORCER) - driver->m_fArmour = Max(driver->m_fArmour, 100.0f); - else if(GetModelIndex() == MI_CABBIE || GetModelIndex() == MI_ZEBRA) // TODO(MIAMI): check zebra - CWorld::Players[CWorld::PlayerInFocus].m_nMoney += 25; bFreebies = false; + switch(GetModelIndex()){ + case MI_AMBULAN: + FindPlayerPed()->m_fHealth = Max(FindPlayerPed()->m_fHealth, Min(FindPlayerPed()->m_fHealth + 20.0f, CWorld::Players[0].m_nMaxHealth)); + break; + + case MI_TAXI: + case MI_CABBIE: + case MI_ZEBRA: + case MI_KAUFMAN: + CWorld::Players[CWorld::PlayerInFocus].m_nMoney += 12; + break; + + case MI_POLICE: + CStreaming::RequestModel(MI_SHOTGUN, STREAMFLAGS_DONT_REMOVE); + bFreebies = true; + break; + + case MI_ENFORCER: + driver->m_fArmour = Max(driver->m_fArmour, CWorld::Players[0].m_nMaxArmour); + break; + + case MI_CADDY: + if(!(driver->IsPlayer() && ((CPlayerPed*)driver)->DoesPlayerWantNewWeapon(WEAPONTYPE_GOLFCLUB, true))) + CStreaming::RequestModel(MI_GOLFCLUB, STREAMFLAGS_DONT_REMOVE); + break; + } } - ApplyTurnForce(0.0f, 0.0f, -0.2f*driver->m_fMass, - driver->GetPosition().x - GetPosition().x, - driver->GetPosition().y - GetPosition().y, - 0.0f); + if(IsBike()) + ApplyMoveForce(-0.2f*driver->m_fMass * GetUp()); + else + ApplyTurnForce(0.0f, 0.0f, -0.2f*driver->m_fMass, + driver->GetPosition().x - GetPosition().x, + driver->GetPosition().y - GetPosition().y, + 0.0f); } bool @@ -1103,10 +1819,13 @@ CVehicle::AddPassenger(CPed *passenger) { int i; - ApplyTurnForce(0.0f, 0.0f, -0.2f*passenger->m_fMass, - passenger->GetPosition().x - GetPosition().x, - passenger->GetPosition().y - GetPosition().y, - 0.0f); + if(IsBike()) + ApplyTurnForce(-0.2f*passenger->m_fMass * GetUp(), -0.1f*GetForward()); + else + ApplyTurnForce(0.0f, 0.0f, -0.2f*passenger->m_fMass, + passenger->GetPosition().x - GetPosition().x, + passenger->GetPosition().y - GetPosition().y, + 0.0f); for(i = 0; i < m_nNumMaxPassengers; i++) if(pPassengers[i] == nil){ @@ -1123,10 +1842,13 @@ CVehicle::AddPassenger(CPed *passenger, uint8 n) if(bIsBus) return AddPassenger(passenger); - ApplyTurnForce(0.0f, 0.0f, -0.2f*passenger->m_fMass, - passenger->GetPosition().x - GetPosition().x, - passenger->GetPosition().y - GetPosition().y, - 0.0f); + if(IsBike()) + ApplyTurnForce(-0.2f*passenger->m_fMass * GetUp(), -0.1f*GetForward()); + else + ApplyTurnForce(0.0f, 0.0f, -0.2f*passenger->m_fMass, + passenger->GetPosition().x - GetPosition().x, + passenger->GetPosition().y - GetPosition().y, + 0.0f); if(n < m_nNumMaxPassengers && pPassengers[n] == nil){ pPassengers[n] = passenger; @@ -1140,6 +1862,22 @@ void CVehicle::RemoveDriver(void) { SetStatus(STATUS_ABANDONED); + if(pDriver == FindPlayerPed()){ + if(GetModelIndex() == MI_POLICE && CStreaming::HasModelLoaded(MI_SHOTGUN)){ + if(bFreebies){ + if(((CPlayerPed*)pDriver)->DoesPlayerWantNewWeapon(WEAPONTYPE_SHOTGUN, true)) + pDriver->GiveWeapon(WEAPONTYPE_SHOTGUN, 5, true); + else + pDriver->GrantAmmo(WEAPONTYPE_SHOTGUN, 5); + bFreebies = false; + } + CStreaming::SetModelIsDeletable(MI_SHOTGUN); + }else if(GetModelIndex() == MI_CADDY && CStreaming::HasModelLoaded(MI_GOLFCLUB)){ + if(((CPlayerPed*)pDriver)->DoesPlayerWantNewWeapon(WEAPONTYPE_GOLFCLUB, true)) + pDriver->GiveWeapon(WEAPONTYPE_GOLFCLUB, 1, true); + CStreaming::SetModelIsDeletable(MI_GOLFCLUB); + } + } pDriver = nil; } @@ -1165,6 +1903,57 @@ CVehicle::RemovePassenger(CPed *p) } } +bool +CVehicle::IsDriver(CPed *ped) +{ + if(ped == nil) + return false; + return ped == pDriver; +} + +bool +CVehicle::IsDriver(int32 model) +{ + return pDriver && pDriver->GetModelIndex() == model; +} + +bool +CVehicle::IsPassenger(CPed *ped) +{ + int i; + if(ped == nil) + return false; + for(i = 0; i < 8; i++) + if(pPassengers[i] == ped) + return true; + return false; +} + +bool +CVehicle::IsPassenger(int32 model) +{ + int i; + for(i = 0; i < 8; i++) + if(pPassengers[i] && pPassengers[i]->GetModelIndex() == model) + return true; + return false; +} + +void +CVehicle::UpdatePassengerList(void) +{ + int i; + bool hasPassenger = false; + if(m_nNumPassengers) + for(i = 0; i < 8; i++) + if(pPassengers[i]){ + hasPassenger = true; + break; + } + if(!hasPassenger) + m_nNumPassengers = 0; +} + void CVehicle::ProcessCarAlarm(void) { @@ -1174,9 +1963,10 @@ CVehicle::ProcessCarAlarm(void) return; step = CTimer::GetTimeStepInMilliseconds(); - if((uint16)m_nAlarmState < step) + if((uint16)m_nAlarmState < step){ m_nAlarmState = 0; - else + m_nCarHornTimer = 0; + }else m_nAlarmState -= step; } @@ -1204,6 +1994,261 @@ CVehicle::IsSphereTouchingVehicle(float sx, float sy, float sz, float radius) return true; } +RpMaterial* +SetCompAlphaCB(RpMaterial *material, void *data) +{ + uint32 alpha = (uint32)(uintptr)data; + RwRGBA *col = (RwRGBA*)RpMaterialGetColor(material); // get rid of const + col->alpha = alpha; + return material; +} + +void +CVehicle::SetComponentAtomicAlpha(RpAtomic *atomic, int32 alpha) +{ + RpGeometry *geo = RpAtomicGetGeometry(atomic); + RpGeometrySetFlags(geo, RpGeometryGetFlags(geo) | rpGEOMETRYMODULATEMATERIALCOLOR); + RpGeometryForAllMaterials(geo, SetCompAlphaCB, (void*)alpha); +} + +void +CVehicle::UpdateClumpAlpha(void) +{ + int clumpAlpha = CVisibilityPlugins::GetClumpAlpha((RpClump*)m_rwObject); + if(bFadeOut){ + clumpAlpha -= 8; + if(clumpAlpha < 0) + clumpAlpha = 0; + }else if(clumpAlpha < 255){ + clumpAlpha += 16; + if(clumpAlpha > 255) + clumpAlpha = 255; + } + CVisibilityPlugins::SetClumpAlpha((RpClump*)m_rwObject, clumpAlpha); +} + +void +CVehicle::HeliDustGenerate(CEntity *heli, float radius, float ground, int rnd) +{ + int i; + float angle; + CColPoint point; + CEntity *entity; + uint8 r, g, b; + + if(heli == nil) + return; + + uint8 surface = SURFACE_TARMAC; + int frm = CTimer::GetFrameCounter() & 7; + float testLowZ = ground - 10.0f; + float dustSize = 0.0f; + float baseSize = 1.0f; + float offset = 1.0f; // when heli is tilted + float particleZ = -101.0f; + int n = 0; + + if(heli->GetModelIndex() == MI_RCGOBLIN || heli->GetModelIndex() == MI_RCRAIDER){ + radius = 3.0f; + dustSize = 0.04f; + baseSize = 0.07f; + offset = 0.3f; + } + + CVector heliPos = heli->GetPosition(); + + if(heli->IsVehicle() && ((CVehicle*)heli)->IsCar()){ + heliPos.x -= (heliPos.z - ground)*heli->GetUp().x*offset*0.5f; + heliPos.y -= (heliPos.z - ground)*heli->GetUp().y*offset*0.5f; + } + + float steamSize = 0.25f * radius * baseSize; + float splashSize = 0.3f * radius * baseSize; + + i = 0; + for(i = 0; i < 32+rnd; i++){ + angle = i * TWOPI/32.0f; + CVector pos(radius*Cos(angle), radius*Sin(angle), 0.0f); + CVector dir = CVector(pos.x, pos.y, 1.0f)*0.01f; + pos += heliPos; + + if(i < 32 && i == 4*frm){ + if(CWorld::ProcessVerticalLine(pos, testLowZ, point, entity, true, false, false, false, true, false, nil)){ + n = rnd; + particleZ = point.point.z; + surface = point.surfaceB; + }else + n = 0; + + float waterLevel = 0.0f; + if(CWaterLevel::GetWaterLevel(pos, &waterLevel, false) && waterLevel > particleZ){ + surface = SURFACE_WATER; + n = rnd; + particleZ = waterLevel; + } + } + + if(n){ + pos.z = particleZ; + if(surface == SURFACE_WATER){ + float red = (0.3*CTimeCycle::GetDirectionalRed() + CTimeCycle::GetAmbientRed_Obj())*255.0f/4.0f; + float green = (0.3*CTimeCycle::GetDirectionalGreen() + CTimeCycle::GetAmbientGreen_Obj())*255.0f/4.0f; + float blue = (0.3*CTimeCycle::GetDirectionalBlue() + CTimeCycle::GetAmbientBlue_Obj())*255.0f/4.0f; + r = clamp(red, 0.0f, 255.0f); + g = clamp(green, 0.0f, 255.0f); + b = clamp(blue, 0.0f, 255.0f); + RwRGBA col1 = { r, g, b, CGeneral::GetRandomNumberInRange(8, 32) }; + RwRGBA col2 = { 255, 255, 255, 32 }; + + if(n&1) + CParticle::AddParticle(PARTICLE_STEAM_NY_SLOWMOTION, pos, dir, nil, steamSize, col2); + else + CParticle::AddParticle(PARTICLE_CAR_SPLASH, pos, dir, nil, splashSize, col1, + CGeneral::GetRandomNumberInRange(0.0f, 10.0f), + CGeneral::GetRandomNumberInRange(0.0f, 90.0f), 1); + }else{ + switch(surface){ + default: + case SURFACE_TARMAC: + r = 10; + g = 10; + b = 10; + break; + case SURFACE_GRASS: + r = 10; + g = 10; + b = 3; + break; + case SURFACE_GRAVEL: + r = 10; + g = 8; + b = 7; + break; + case SURFACE_MUD_DRY: + r = 10; + g = 6; + b = 3; + break; + case SURFACE_SAND: + case SURFACE_SAND_BEACH: + r = 10; + g = 10; + b = 7; + break; + } + RwRGBA col = { r, g, b, 32 }; + if(heliPos.z - pos.z < 20.0f) + CParticle::AddParticle(PARTICLE_HELI_DUST, pos, dir, nil, dustSize, col); + } + + n--; + } + } +} + +#define GLARE_MIN_DIST (13.0f) +#define GLARE_FULL_DIST (30.0f) +#define GLARE_MIN_ANGLE (0.99f) +#define GLARE_FULL_ANGLE (0.995f) + +void +CVehicle::DoSunGlare(void) +{ + if(bRenderScorched || GetPosition().z < 0.0f || + GetVehicleAppearance() != VEHICLE_APPEARANCE_CAR || CWeather::SunGlare <= 0.0f) + return; + + CVector camDir = TheCamera.GetPosition() - GetPosition(); + float dist = camDir.Magnitude(); + camDir *= 2.0f/dist; + CVector glareVec = camDir + CTimeCycle::GetSunDirection(); + CVector localGlareVec; + localGlareVec.x = DotProduct(glareVec, GetRight()); + localGlareVec.y = DotProduct(glareVec, GetForward()); + localGlareVec.z = 0.0; + localGlareVec.Normalise(); + + CVector2D fwd2D = GetForward(); + fwd2D.Normalise(); + CVector2D camDir2D = camDir; + camDir2D.Normalise(); + float fwdness = Abs(DotProduct2D(fwd2D, camDir2D)); + + // check angle + float strength; + if(fwdness > GLARE_FULL_ANGLE) + strength = 1.0f; + else if(fwdness > GLARE_MIN_ANGLE) + strength = (fwdness - GLARE_MIN_ANGLE)/(GLARE_FULL_ANGLE-GLARE_MIN_ANGLE); + else + return; + // check distance + if(dist > GLARE_FULL_DIST){ + // no max distance + }else if(dist > GLARE_MIN_DIST) + strength *= (dist - GLARE_MIN_DIST)/(GLARE_FULL_DIST - GLARE_MIN_DIST); + else + return; + + float intens = 0.8f * strength * CWeather::SunGlare; + int r = intens * (CTimeCycle::GetSunCoreRed() + 2*255)/3.0f; + int g = intens * (CTimeCycle::GetSunCoreGreen() + 2*255)/3.0f; + int b = intens * (CTimeCycle::GetSunCoreBlue() + 2*255)/3.0f; + + CColModel *colmodel = GetColModel(); + CCollision::CalculateTrianglePlanes(colmodel); + + int i; + for(i = 0; i < colmodel->numTriangles-2; i += 2){ + int a1 = colmodel->triangles[i].a; + int b1 = colmodel->triangles[i].b; + int c1 = colmodel->triangles[i].c; + int a2 = colmodel->triangles[i+1].a; + int b2 = colmodel->triangles[i+1].b; + int c2 = colmodel->triangles[i+1].c; + CVector vert1 = colmodel->vertices[a1]; + CVector vert4; + // Need an upward surface + if(vert1.z <= 0.0f) + continue; + + // trying to find a quad here + int numTri2Verts = 0; + if(a2 != a1 && a2 != b1 && a2 != c1){ + // a2 is not in tri1 + numTri2Verts++; + vert4 = colmodel->vertices[a2]; + } + if(b2 != a1 && b2 != b1 && b2 != c1){ + // b2 is not in tri1 + numTri2Verts++; + vert4 = colmodel->vertices[b2]; + } + if(c2 != a1 && c2 != b1 && c2 != c1){ + // c2 is not in tri1 + numTri2Verts++; + vert4 = colmodel->vertices[c2]; + } + // Need exactly one vertex from tri2 for a quad with tri1 + if(numTri2Verts != 1) + continue; + + CVector mid = (vert1 + colmodel->vertices[b1] + colmodel->vertices[c1] + vert4)/4.0f; + float dy = mid.y - vert1.y; + float dx = mid.x - vert1.x; + float dist = 1.4f * Min(Abs(dx), Abs(dy)); + if(dist > 0.6f){ + CVector pos = GetMatrix() * (dist * localGlareVec + mid) + camDir; + CCoronas::RegisterCorona((uintptr)this + 27 + i, + r, g, b, 255, + pos, 0.9f*CWeather::SunGlare, 90.0f, + CCoronas::TYPE_STAR, CCoronas::FLARE_NONE, + CCoronas::REFLECTION_OFF, CCoronas::LOSCHECK_OFF, + CCoronas::STREAK_OFF, 0.0f); + } + } +} + void DestroyVehicleAndDriverAndPassengers(CVehicle* pVehicle) { @@ -1347,19 +2392,33 @@ CVehicle::Load(uint8*& buf) #endif eVehicleAppearance -//--MIAMI: TODO, implement VC version, appearance != type -// This would work for cars, boats and bikes but not for planes and helis CVehicle::GetVehicleAppearance(void) { - if (IsCar()) - return VEHICLE_CAR; - if (IsBoat()) - return VEHICLE_BOAT; - if (IsBike()) - return VEHICLE_BIKE; - if (IsPlane()) - return VEHICLE_PLANE; - if (IsHeli()) - return VEHICLE_HELI; - return VEHICLE_NONE; + uint32 flags = pHandling->Flags & 0xF0000; + if (flags == 0) + return VEHICLE_APPEARANCE_CAR; + if (flags == HANDLING_IS_BIKE) + return VEHICLE_APPEARANCE_BIKE; + if (flags == HANDLING_IS_HELI) + return VEHICLE_APPEARANCE_HELI; + if (flags == HANDLING_IS_PLANE) + return VEHICLE_APPEARANCE_PLANE; + if (flags == HANDLING_IS_BOAT) + return VEHICLE_APPEARANCE_BOAT; + return VEHICLE_APPEARANCE_NONE; +} + +bool +IsVehiclePointerValid(CVehicle* pVehicle) +{ + if (!pVehicle) + return false; + int index = CPools::GetVehiclePool()->GetJustIndex(pVehicle); +#ifdef FIX_BUGS + if (index < 0 || index >= NUMVEHICLES) +#else + if (index < 0 || index > NUMVEHICLES) +#endif + return false; + return pVehicle->m_vehType == VEHICLE_TYPE_PLANE || pVehicle->m_entryInfoList.first; } diff --git a/src/vehicles/Vehicle.h b/src/vehicles/Vehicle.h index cdf0595a..083a8a15 100644 --- a/src/vehicles/Vehicle.h +++ b/src/vehicles/Vehicle.h @@ -8,6 +8,8 @@ #include "HandlingMgr.h" class CPed; +class CPlayerPed; +class CCopPed; class CFire; struct tHandlingData; @@ -87,8 +89,8 @@ enum CAR_PIECE_WING_LR, CAR_PIECE_WING_RR, CAR_PIECE_WHEEL_LF, - CAR_PIECE_WHEEL_LR, CAR_PIECE_WHEEL_RF, + CAR_PIECE_WHEEL_LR, CAR_PIECE_WHEEL_RR, CAR_PIECE_WINDSCREEN, }; @@ -104,30 +106,46 @@ enum tWheelState enum eFlightModel { FLIGHT_MODEL_DODO, - // not used in III FLIGHT_MODEL_RCPLANE, - FLIGHT_MODEL_HELI, - FLIGHT_MODEL_SEAPLANE + FLIGHT_MODEL_RCHELI, + FLIGHT_MODEL_SEAPLANE, + FLIGHT_MODEL_PLANE_UNUSED, + FLIGHT_MODEL_PLANE, + FLIGHT_MODEL_HELI }; enum eVehicleAppearance { - VEHICLE_NONE, - VEHICLE_CAR, - VEHICLE_BIKE, - VEHICLE_HELI, - VEHICLE_BOAT, - VEHICLE_PLANE, + VEHICLE_APPEARANCE_NONE, + VEHICLE_APPEARANCE_CAR, + VEHICLE_APPEARANCE_BIKE, + VEHICLE_APPEARANCE_HELI, + VEHICLE_APPEARANCE_BOAT, + VEHICLE_APPEARANCE_PLANE, }; -// Or Weapon.h? -void FireOneInstantHitRound(CVector *shotSource, CVector *shotTarget, int32 damage); +// TODO +enum eBikeWheelSpecial +{ + BIKE_WHEEL_2 = 2, + BIKE_WHEEL_3, +}; + +enum +{ + ROTOR_TOP = 3, + ROTOR_FRONT = 4, + ROTOR_RIGHT = 5, + ROTOR_LEFT = 7, + ROTOR_BACK = 8, + ROTOR_BOTTOM = 9, +}; class CVehicle : public CPhysical { public: - // 0x128 tHandlingData *pHandling; + tFlyingHandlingData *pFlyingHandling; CAutoPilot AutoPilot; uint8 m_currentColour1; uint8 m_currentColour2; @@ -182,22 +200,29 @@ public: uint8 bVehicleColProcessed : 1;// Has ProcessEntityCollision been processed for this car? uint8 bIsCarParkVehicle : 1; // Car has been created using the special CAR_PARK script command uint8 bHasAlreadyBeenRecorded : 1; // Used for replays - uint8 bPartOfConvoy : 1; + uint8 bHeliMinimumTilt : 1; // This heli should have almost no tilt really + uint8 bAudioChangingGear : 1; // sounds like vehicle is changing gear + + uint8 bIsDrowning : 1; // is vehicle occupants taking damage in water (i.e. vehicle is dead in water) + uint8 bTyresDontBurst : 1; // If this is set the tyres are invincible uint8 bCreatedAsPoliceVehicle : 1;// True if this guy was created as a police vehicle (enforcer, policecar, miamivice car etc) + uint8 bRestingOnPhysical : 1; // Dont go static cause car is sitting on a physical object that might get removed uint8 bParking : 1; + uint8 bCanPark : 1; uint8 m_bombType : 3; + uint8 bDriverLastFrame : 1; int8 m_numPedsUseItAsCover; uint8 m_nAmmoInClip; // Used to make the guns on boat do a reload (20 by default) int8 m_nPacManPickupsCarried; uint8 m_nRoadblockType; - int16 m_nRoadblockNode; float m_fHealth; // 1000.0f = full health. 250.0f = fire. 0 -> explode uint8 m_nCurrentGear; float m_fChangeGearTime; CEntity* m_pBombRigger; + uint32 m_nSetPieceExtendedRangeTime; uint32 m_nGunFiringTime; // last time when gun on vehicle was fired (used on boats) uint32 m_nTimeOfDeath; uint16 m_nTimeBlocked; @@ -207,12 +232,14 @@ public: float m_fMapObjectHeightBehind; // rear Z? eCarLock m_nDoorLock; int8 m_nLastWeaponDamage; // see eWeaponType, -1 if no damage + CEntity *m_pLastDamageEntity; int8 m_nRadioStation; uint8 m_bRainAudioCounter; uint8 m_bRainSamplesCounter; - uint8 m_nCarHornTimer; - uint8 m_nCarHornPattern; // last horn? + uint32 m_nCarHornTimer; + uint8 m_nCarHornPattern; bool m_bSirenOrAlarm; + uint8 m_nCarHornDelay; int8 m_comedyControlState; CStoredCollPoly m_aCollPolys[2]; // poly which is under front/rear part of car float m_fSteerRatio; @@ -242,11 +269,15 @@ public: virtual bool IsDoorFullyOpen(eDoors door) { return false; } virtual bool IsDoorClosed(eDoors door) { return false; } virtual bool IsDoorMissing(eDoors door) { return false; } + virtual bool IsDoorReady(uint32 door) { return false; } + virtual bool IsDoorMissing(uint32 door) { return false; } + virtual bool IsOpenTopCar(void) { return false; } virtual void RemoveRefsToVehicle(CEntity *ent) {} virtual void BlowUpCar(CEntity *ent) {} virtual bool SetUpWheelColModel(CColModel *colModel) { return false; } - virtual void BurstTyre(uint8 tyre) {} + virtual void BurstTyre(uint8 tyre, bool applyForces) {} virtual bool IsRoomForPedToLeaveCar(uint32 component, CVector *forcedDoorPos) { return false;} + virtual bool IsClearToDriveAway(void); virtual float GetHeightAboveRoad(void); virtual void PlayCarHorn(void) {} #ifdef COMPATIBLE_SAVES @@ -263,11 +294,17 @@ public: bool IsBike(void) { return m_vehType == VEHICLE_TYPE_BIKE; } void FlyingControl(eFlightModel flightModel); + bool DoBladeCollision(CVector pos, CMatrix &matrix, int16 rotorType, float radius, float damageMult); + bool BladeColSectorList(CPtrList &list, CColModel &rotorColModel, CMatrix &matrix, int16 rotorType, float damageMult); + void ProcessWheel(CVector &wheelFwd, CVector &wheelRight, CVector &wheelContactSpeed, CVector &wheelContactPoint, int32 wheelsOnGround, float thrust, float brake, float adhesion, int8 wheelId, float *wheelSpeed, tWheelState *wheelState, uint16 wheelStatus); + void ProcessBikeWheel(CVector &wheelFwd, CVector &wheelRight, CVector &wheelContactSpeed, CVector &wheelContactPoint, + int32 wheelsOnGround, float thrust, float brake, float adhesion, float unk, int8 wheelId, float *wheelSpeed, tWheelState *wheelState, eBikeWheelSpecial special, uint16 wheelStatus); void ExtinguishCarFire(void); void ProcessDelayedExplosion(void); float ProcessWheelRotation(tWheelState state, const CVector &fwd, const CVector &speed, float radius); + int FindTyreNearestPoint(float x, float y); bool IsLawEnforcementVehicle(void); void ChangeLawEnforcerState(uint8 enable); bool UsesSiren(uint32 id); @@ -277,8 +314,10 @@ public: bool IsOnItsSide(void); bool CanBeDeleted(void); bool CanPedOpenLocks(CPed *ped); + bool CanDoorsBeDamaged(void); bool CanPedEnterCar(void); - bool CanPedExitCar(void); + bool CanPedExitCar(bool jumpExit); + bool CanPedJumpOffBike(void); // do these two actually return something? CPed *SetUpDriver(void); CPed *SetupPassenger(int n); @@ -287,19 +326,32 @@ public: bool AddPassenger(CPed *passenger, uint8 n); void RemovePassenger(CPed *passenger); void RemoveDriver(void); + bool IsDriver(CPed *ped); + bool IsDriver(int32 model); + bool IsPassenger(CPed *ped); + bool IsPassenger(int32 model); + void UpdatePassengerList(void); void ProcessCarAlarm(void); bool IsSphereTouchingVehicle(float sx, float sy, float sz, float radius); bool ShufflePassengersToMakeSpace(void); - void InflictDamage(CEntity *damagedBy, eWeaponType weaponType, float damage); + void MakeNonDraggedPedsLeaveVehicle(CPed *ped1, CPed *ped2, CPlayerPed *&player, CCopPed *&cop); + void InflictDamage(CEntity *damagedBy, eWeaponType weaponType, float damage, CVector pos = CVector(0.0f, 0.0f, 0.0f)); void DoFixedMachineGuns(void); void FireFixedMachineGuns(void); + void ActivateBomb(void); + void ActivateBombWhenEntered(void); + void SetComponentAtomicAlpha(RpAtomic *atomic, int32 alpha); + void UpdateClumpAlpha(void); + + static void HeliDustGenerate(CEntity *heli, float radius, float ground, int rnd); + void DoSunGlare(void); bool IsAlarmOn(void) { return m_nAlarmState != 0 && m_nAlarmState != -1; } CVehicleModelInfo* GetModelInfo() { return (CVehicleModelInfo*)CModelInfo::GetModelInfo(GetModelIndex()); } bool IsTaxi(void) { return GetModelIndex() == MI_TAXI || GetModelIndex() == MI_CABBIE || GetModelIndex() == MI_ZEBRA || GetModelIndex() == MI_KAUFMAN; } + bool IsLimo(void) { return GetModelIndex() == MI_STRETCH || GetModelIndex() == MI_LOVEFIST; } bool IsRealHeli(void) { return !!(pHandling->Flags & HANDLING_IS_HELI); } - AnimationId GetDriverAnim(void) { return IsCar() && bLowVehicle ? ANIM_CAR_LSIT : (IsBoat() && GetModelIndex() != MI_SPEEDER ? ANIM_DRIVE_BOAT : ANIM_CAR_SIT); } static bool bWheelsOnlyCheat; static bool bAllDodosCheat; @@ -310,6 +362,9 @@ public: static bool bAltDodoCheat; #endif static bool m_bDisableMouseSteering; + static bool bDisableRemoteDetonation; + static bool bDisableRemoteDetonationOnContact; }; void DestroyVehicleAndDriverAndPassengers(CVehicle* pVehicle); +bool IsVehiclePointerValid(CVehicle* pVehicle); diff --git a/src/weapons/ShotInfo.cpp b/src/weapons/ShotInfo.cpp index f09ae052..6fc6341d 100644 --- a/src/weapons/ShotInfo.cpp +++ b/src/weapons/ShotInfo.cpp @@ -128,4 +128,4 @@ CShotInfo::Update() if (!((CTimer::GetFrameCounter() + slot) & 3)) CWorld::SetCarsOnFire(shot.m_startPos.x, shot.m_startPos.y, shot.m_startPos.z, 4.0f, shot.m_sourceEntity); } -} \ No newline at end of file +} diff --git a/src/weapons/Weapon.cpp b/src/weapons/Weapon.cpp index deb77cb9..eaf86bfc 100644 --- a/src/weapons/Weapon.cpp +++ b/src/weapons/Weapon.cpp @@ -29,28 +29,51 @@ #include "WaterLevel.h" #include "WeaponInfo.h" #include "World.h" +#include "SurfaceTable.h" -uint16 gReloadSampleTime[WEAPONTYPE_LAST_WEAPONTYPE] = +// TODO(Miami) +#define AUDIO_NOT_READY + +// TODO(Miami): Those are mostly placeholders!!! +uint16 gReloadSampleTime[] = { 0, // UNARMED - 0, // BASEBALLBAT + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, // GRENADE + 0, // DETONATEGRENADE + 0, // TEARGAS + 0, // MOLOTOV + 0, // ROCKET 250, // COLT45 + 250, // PYTHON + 650, // SHOTGUN + 650, // SPAS12 SHOTGUN + 650, // STUBBY SHOTGUN 400, // TEC9 400, // UZIhec 400, // SILENCED_INGRAM 400, // MP5 - 650, // SHOTGUN - 300, // AK47 300, // M16 + 300, // AK47 423, // SNIPERRIFLE + 423, // LASERSCOPE 400, // ROCKETLAUNCHER 0, // FLAMETHROWER - 0, // MOLOTOV - 0, // ROCKET - 0, // GRENADE - 0, // DETONATEGRENADE + 0, // M60 + 0, // MINIGUN 0, // DETONATOR - 0 // HELICANNON + 0, // HELICANNON + 0 // CAMERA }; CWeaponInfo * @@ -96,10 +119,7 @@ CWeapon::Initialise(eWeaponType type, int32 ammo) { m_eWeaponType = type; m_eWeaponState = WEAPONSTATE_READY; - if (ammo > 99999) - m_nAmmoTotal = 99999; - else - m_nAmmoTotal = ammo; + m_nAmmoTotal = Min(ammo, 99999); m_nAmmoInClip = 0; Reload(); m_nTimer = 0; @@ -156,6 +176,7 @@ CWeapon::Fire(CEntity *shooter, CVector *fireSource) return false; bool fired; + bool addFireRateAsDelay = true; if ( GetInfo()->m_eWeaponFire != WEAPON_FIRE_MELEE ) { @@ -165,33 +186,40 @@ CWeapon::Fire(CEntity *shooter, CVector *fireSource) switch ( m_eWeaponType ) { case WEAPONTYPE_SHOTGUN: + case WEAPONTYPE_SPAS12_SHOTGUN: + case WEAPONTYPE_STUBBY_SHOTGUN: { + addFireRateAsDelay = true; fired = FireShotgun(shooter, source); break; } case WEAPONTYPE_COLT45: + case WEAPONTYPE_PYTHON: case WEAPONTYPE_UZI: case WEAPONTYPE_TEC9: case WEAPONTYPE_SILENCED_INGRAM: case WEAPONTYPE_MP5: - case WEAPONTYPE_AK47: - case WEAPONTYPE_M16: + case WEAPONTYPE_M4: + case WEAPONTYPE_RUGER: + case WEAPONTYPE_M60: + case WEAPONTYPE_MINIGUN: case WEAPONTYPE_HELICANNON: { if ((TheCamera.PlayerWeaponMode.Mode == CCam::MODE_HELICANNON_1STPERSON || TheCamera.PlayerWeaponMode.Mode == CCam::MODE_M16_1STPERSON) - && shooter == FindPlayerPed()) - { + && shooter == FindPlayerPed()) { + addFireRateAsDelay = false; fired = FireM16_1stPerson(shooter); - } - else + } else { + addFireRateAsDelay = true; fired = FireInstantHit(shooter, source); - + } break; } case WEAPONTYPE_SNIPERRIFLE: + case WEAPONTYPE_LASERSCOPE: { fired = FireSniper(shooter); @@ -218,6 +246,7 @@ CWeapon::Fire(CEntity *shooter, CVector *fireSource) case WEAPONTYPE_MOLOTOV: case WEAPONTYPE_GRENADE: case WEAPONTYPE_DETONATOR_GRENADE: + case WEAPONTYPE_TEARGAS: { if ( shooter == FindPlayerPed() ) { @@ -267,51 +296,58 @@ CWeapon::Fire(CEntity *shooter, CVector *fireSource) } } - if ( fired ) + if (fired) { bool isPlayer = false; - if ( shooter->IsPed() ) + if (shooter->IsPed()) { - CPed *shooterPed = (CPed*)shooter; + CPed* shooterPed = (CPed*)shooter; shooterPed->bIsShooting = true; - if ( shooterPed->IsPlayer() ) + if (shooterPed->IsPlayer()) isPlayer = true; DMAudio.PlayOneShot(shooterPed->m_audioEntityId, SOUND_WEAPON_SHOT_FIRED, 0.0f); } - if ( m_nAmmoInClip > 0 ) m_nAmmoInClip--; - if ( m_nAmmoTotal > 0 && (m_nAmmoTotal < 25000 || isPlayer) ) m_nAmmoTotal--; + if (m_nAmmoInClip > 0) + m_nAmmoInClip--; - if ( m_eWeaponState == WEAPONSTATE_READY && m_eWeaponType == WEAPONTYPE_FLAMETHROWER ) + if (m_nAmmoTotal > 0 && (m_nAmmoTotal < 25000 || isPlayer) && (!isPlayer || CStats::GetPercentageProgress() < 100.0f || m_eWeaponType == WEAPONTYPE_DETONATOR)) + m_nAmmoTotal--; + + if (m_eWeaponState == WEAPONSTATE_READY && m_eWeaponType == WEAPONTYPE_FLAMETHROWER) DMAudio.PlayOneShot(((CPhysical*)shooter)->m_audioEntityId, SOUND_WEAPON_FLAMETHROWER_FIRE, 0.0f); m_eWeaponState = WEAPONSTATE_FIRING; - } - if ( m_nAmmoInClip == 0 ) - { - if ( m_nAmmoTotal == 0 ) - return true; - - m_eWeaponState = WEAPONSTATE_RELOADING; - m_nTimer = CTimer::GetTimeInMilliseconds() + GetInfo()->m_nReload; - - if ( shooter == FindPlayerPed() ) + if (m_nAmmoInClip == 0) { - if ( CWorld::Players[CWorld::PlayerInFocus].m_bFastReload ) - m_nTimer = CTimer::GetTimeInMilliseconds() + GetInfo()->m_nReload / 4; + if (m_nAmmoTotal == 0) + return true; + + m_eWeaponState = WEAPONSTATE_RELOADING; + m_nTimer = CTimer::GetTimeInMilliseconds() + GetInfo()->m_nReload; + + if (shooter == FindPlayerPed()) + { + if (CWorld::Players[CWorld::PlayerInFocus].m_bFastReload) + m_nTimer = CTimer::GetTimeInMilliseconds() + GetInfo()->m_nReload / 4; + } + + return true; } - return true; - } + if (addFireRateAsDelay) + m_nTimer = CTimer::GetTimeInMilliseconds() + GetInfo()->m_nFiringRate; + else + m_nTimer = CTimer::GetTimeInMilliseconds(); - m_nTimer = CTimer::GetTimeInMilliseconds() + 1000; - if ( shooter == FindPlayerPed() ) - CStats::RoundsFiredByPlayer++; + if (shooter == FindPlayerPed()) + CStats::RoundsFiredByPlayer++; + } } else { @@ -319,9 +355,15 @@ CWeapon::Fire(CEntity *shooter, CVector *fireSource) { m_nTimer = CTimer::GetTimeInMilliseconds() + GetInfo()->m_nReload; m_eWeaponState = WEAPONSTATE_FIRING; +#ifndef AUDIO_NOT_READY + if (shooter->IsPed() && m_eWeaponType != WEAPONTYPE_CHAINSAW) + { + DMAudio.PlayOneShot(((CPed*)shooter)->m_audioEntityId, 188, m_eWeaponType << 8); + } +#endif } - FireMelee(shooter, *source); + fired = FireMelee(shooter, *source); } if ( m_eWeaponType == WEAPONTYPE_UNARMED || m_eWeaponType == WEAPONTYPE_BASEBALLBAT ) @@ -331,7 +373,7 @@ CWeapon::Fire(CEntity *shooter, CVector *fireSource) } bool -CWeapon::FireFromCar(CAutomobile *shooter, bool left) +CWeapon::FireFromCar(CVehicle *shooter, bool left) { ASSERT(shooter!=nil); @@ -369,7 +411,7 @@ CWeapon::FireFromCar(CAutomobile *shooter, bool left) return true; } -// --MIAMI: Just a few lines is done +// --MIAMI: Done, except commented things bool CWeapon::FireMelee(CEntity *shooter, CVector &fireSource) { @@ -383,20 +425,33 @@ CWeapon::FireMelee(CEntity *shooter, CVector &fireSource) CPed *shooterPed = (CPed*)shooter; + if (shooterPed == FindPlayerPed()) { + if (m_eWeaponType == WEAPONTYPE_GOLFCLUB || m_eWeaponType == WEAPONTYPE_NIGHTSTICK || + (m_eWeaponType >= WEAPONTYPE_BASEBALLBAT && m_eWeaponType <= WEAPONTYPE_CHAINSAW)) { + + // TODO(Miami): BreakGlassPhysically + if (m_eWeaponType == WEAPONTYPE_CHAINSAW) { + CEventList::RegisterEvent(EVENT_GUNSHOT, EVENT_ENTITY_PED, FindPlayerPed(), FindPlayerPed(), 1000); + } + } + } + + int damageEntityRegistered = 0; + for ( int32 i = 0; i < shooterPed->m_numNearPeds; i++ ) { CPed *victimPed = shooterPed->m_nearPeds[i]; ASSERT(victimPed!=nil); if ( (victimPed->m_nPedType != shooterPed->m_nPedType || victimPed == shooterPed->m_pSeekTarget) - && victimPed != shooterPed->m_leader || !(CGeneral::GetRandomNumber() & 31) ) + && victimPed != shooterPed->m_leader || !(CGeneral::GetRandomNumber() & 31) + && (!shooterPed->IsGangMember() || victimPed->CanBeDamagedByThisGangMember(shooterPed)) ) { bool collided = false; - CColModel *victimPedCol = &CTempColModels::ms_colModelPed1; - if ( victimPed->OnGround() || !victimPed->IsPedHeadAbovePos(-0.3f) ) - victimPedCol = &CTempColModels::ms_colModelPedGroundHit; - + if (victimPed->m_nPedState == PED_DRIVING && (m_eWeaponType == WEAPONTYPE_UNARMED || m_eWeaponType == WEAPONTYPE_BRASSKNUCKLE + || info->m_bFightMode)) + continue; float victimPedRadius = victimPed->GetBoundRadius() + info->m_fRadius; if ( victimPed->bUsesCollision || victimPed->Dead() || victimPed->Driving() ) @@ -405,12 +460,29 @@ CWeapon::FireMelee(CEntity *shooter, CVector &fireSource) if ( SQR(victimPedRadius) > (victimPedPos-(*fireSource)).MagnitudeSqr() ) { CVector collisionDist; + CColModel* victimPedCol = &CTempColModels::ms_colModelPed1; + bool useLocalPos = false; + if (victimPed->m_nPedState == PED_FALL + || victimPed->m_nPedState == PED_DIE && victimPed->bIsPedDieAnimPlaying + || victimPed->m_nWaitState == WAITSTATE_SIT_IDLE + || victimPed->m_nWaitState == WAITSTATE_SUN_BATHE_IDLE) + { + useLocalPos = true; + victimPedCol = ((CPedModelInfo*)CModelInfo::GetModelInfo(victimPed->GetModelIndex()))->AnimatePedColModelSkinnedWorld(victimPed->GetClump()); + } else if (victimPed->DyingOrDead()) { + victimPedCol = &CTempColModels::ms_colModelPedGroundHit; + } int32 s = 0; while ( s < victimPedCol->numSpheres ) { CColSphere *sphere = &victimPedCol->spheres[s]; - collisionDist = victimPedPos+sphere->center-(*fireSource); + + if (useLocalPos) { + collisionDist = sphere->center - (*fireSource); + } else { + collisionDist = victimPedPos + sphere->center - (*fireSource); + } if ( SQR(sphere->radius + info->m_fRadius) > collisionDist.MagnitudeSqr() ) { @@ -431,65 +503,115 @@ CWeapon::FireMelee(CEntity *shooter, CVector &fireSource) int32 localDir = victimPed->GetLocalDirection(posOffset); - bool isBat = m_eWeaponType == WEAPONTYPE_BASEBALLBAT; + bool isHeavy = m_eWeaponType >= WEAPONTYPE_GOLFCLUB && m_eWeaponType <= WEAPONTYPE_KATANA && m_eWeaponType != WEAPONTYPE_HAMMER; + + if (shooterPed->m_fDamageImpulse == 0.0f) { + shooterPed->m_pDamageEntity = victimPed; + victimPed->RegisterReference(&shooterPed->m_pDamageEntity); + } + + damageEntityRegistered = 3; + // TODO(Miami): Bike if ( !victimPed->DyingOrDead() ) victimPed->ReactToAttack(shooterPed); uint8 hitLevel = HITLEVEL_HIGH; - if ( isBat && victimPed->OnGround() ) + if ( isHeavy && (victimPed->OnGround() || victimPed->m_nWaitState == WAITSTATE_SUN_BATHE_IDLE)) hitLevel = HITLEVEL_GROUND; victimPed->StartFightDefend(localDir, hitLevel, 10); if ( !victimPed->DyingOrDead() ) { - if ( shooterPed->IsPlayer() && isBat && anim2Playing ) + if ( shooterPed->IsPlayer() && isHeavy && anim2Playing ) victimPed->InflictDamage(shooterPed, m_eWeaponType, 100.0f, PEDPIECE_TORSO, localDir); else if ( shooterPed->IsPlayer() && ((CPlayerPed*)shooterPed)->m_bAdrenalineActive ) victimPed->InflictDamage(shooterPed, m_eWeaponType, 3.5f*info->m_nDamage, PEDPIECE_TORSO, localDir); else { - if ( victimPed->IsPlayer() && isBat ) // wtf, it's not fair + if ( victimPed->IsPlayer() && isHeavy ) // wtf, it's not fair victimPed->InflictDamage(shooterPed, m_eWeaponType, 2.0f*info->m_nDamage, PEDPIECE_TORSO, localDir); else victimPed->InflictDamage(shooterPed, m_eWeaponType, info->m_nDamage, PEDPIECE_TORSO, localDir); } } - if ( CGame::nastyGame ) + if ( CGame::nastyGame && victimPed->GetIsOnScreen() ) { - if ( victimPed->GetIsOnScreen() ) + CVector dir = collisionDist * RecipSqrt(1.0f, 10.0f*collisionDist.MagnitudeSqr()); + + CParticle::AddParticle(PARTICLE_BLOOD, bloodPos, dir); + CParticle::AddParticle(PARTICLE_BLOOD, bloodPos, dir); + CParticle::AddParticle(PARTICLE_BLOOD, bloodPos, dir); + + if ( isHeavy ) { - CVector dir = collisionDist * RecipSqrt(1.0f, 10.0f*collisionDist.MagnitudeSqr()); - - CParticle::AddParticle(PARTICLE_BLOOD, bloodPos, dir); - CParticle::AddParticle(PARTICLE_BLOOD, bloodPos, dir); + dir.x += CGeneral::GetRandomNumberInRange(-0.05f, 0.05f); + dir.y += CGeneral::GetRandomNumberInRange(-0.05f, 0.05f); CParticle::AddParticle(PARTICLE_BLOOD, bloodPos, dir); - if ( isBat ) + dir.x += CGeneral::GetRandomNumberInRange(-0.05f, 0.05f); + dir.y += CGeneral::GetRandomNumberInRange(-0.05f, 0.05f); + CParticle::AddParticle(PARTICLE_BLOOD, bloodPos, dir); + } + + if (m_eWeaponType == WEAPONTYPE_CHAINSAW) + { + if (victimPed->m_nPedState != PED_DEAD && !((CTimer::GetFrameCounter() + 17) & 1) + || victimPed->m_nPedState == PED_DEAD && !((CTimer::GetFrameCounter() + 17) & 3)) { - dir.x += CGeneral::GetRandomNumberInRange(-0.05f, 0.05f); - dir.y += CGeneral::GetRandomNumberInRange(-0.05f, 0.05f); - CParticle::AddParticle(PARTICLE_BLOOD, bloodPos, dir); - - dir.x += CGeneral::GetRandomNumberInRange(-0.05f, 0.05f); - dir.y += CGeneral::GetRandomNumberInRange(-0.05f, 0.05f); - CParticle::AddParticle(PARTICLE_BLOOD, bloodPos, dir); + CParticle::AddParticle(PARTICLE_TEST, bloodPos, CVector(0.0f, 0.0f, 0.0f), nil, 0.2f); } + CVector newDir(dir); + newDir.z += 0.2f; + CParticle::AddParticle(PARTICLE_BLOOD_SMALL, bloodPos, newDir); + CParticle::AddParticle(PARTICLE_BLOOD, bloodPos, newDir); + newDir.z = dir.z + 0.1f; + CParticle::AddParticle(PARTICLE_BLOOD, bloodPos, newDir); + newDir.x = 0.0f; + newDir.y = 0.0f; + newDir.z = 0.01f; + CParticle::AddParticle(PARTICLE_DEBRIS2, bloodPos, newDir); + + // TODO(Miami): New particle + /* + v116.z = 0.0; + v116.x = CGeneral::GetRandomNumberInRange(-0.15f, 0.15f); + v116.y = CGeneral::GetRandomNumberInRange(0.1f, 0.35f); + v115.x = CGeneral::GetRandomNumberInRange(SCREEN_STRETCH_X(50.0f), SCREEN_STRETCH_FROM_RIGHT(50.0f)); + v115.z = 1.0; + v115.y = CGeneral::GetRandomNumberInRange(SCREEN_STRETCH_Y(50.0f), SCREEN_STRETCH_FROM_BOTTOM(50.0f)); + CParticle::AddParticle(41, v115, v116, nil, CGeneral::GetRandomNumberInRange(0.1f, 0.15f), + CRGBA(0, 0, 0, 0), 0, 0, CGeneral::GetRandomNumber() & 1, 0); + + */ + } + if (info->m_AnimToPlay == ASSOCGRP_KNIFE) + { + dir.x += 0.1f * shooterPed->GetUp().x + 0.05f * shooterPed->GetRight().x; + dir.y += 0.1f * shooterPed->GetUp().y + 0.05f * shooterPed->GetRight().y; + dir.z += 0.1f * shooterPed->GetUp().z + 0.05f * shooterPed->GetRight().z; + CParticle::AddParticle(PARTICLE_BLOOD_SPURT, bloodPos, dir); + CParticle::AddParticle(PARTICLE_BLOOD_SPURT, bloodPos, dir); + CParticle::AddParticle(PARTICLE_BLOOD_SPURT, bloodPos, dir); } } if ( !victimPed->OnGround() ) { if ( victimPed->m_fHealth > 0.0f - && (victimPed->m_fHealth < 20.0f && victimPedHealth > 20.0f || isBat && !victimPed->IsPlayer()) ) + && (victimPed->m_fHealth < 30.0f && victimPedHealth > 20.0f || + (isHeavy || m_eWeaponType == WEAPONTYPE_BRASSKNUCKLE) && !victimPed->IsPlayer()) ) { posOffset.Normalise(); victimPed->bIsStanding = false; - victimPed->ApplyMoveForce(posOffset.x*-5.0f, posOffset.y*-5.0f, 3.0f); + if(m_eWeaponType == WEAPONTYPE_CHAINSAW) + victimPed->ApplyMoveForce(posOffset.x*-2.0f, posOffset.y*-2.0f, 2.0f); + else + victimPed->ApplyMoveForce(posOffset.x*-5.0f, posOffset.y*-5.0f, 3.0f); - if ( isBat && victimPed->IsPlayer() ) + if ( isHeavy && victimPed->IsPlayer() ) victimPed->SetFall(3000, AnimationId(ANIM_KO_SKID_FRONT + localDir), false); else victimPed->SetFall(1500, AnimationId(ANIM_KO_SKID_FRONT + localDir), false); @@ -502,21 +624,152 @@ CWeapon::FireMelee(CEntity *shooter, CVector &fireSource) { posOffset.Normalise(); victimPed->bIsStanding = false; - victimPed->ApplyMoveForce(posOffset.x*-5.0f, posOffset.y*-5.0f, 3.0f); + if(m_eWeaponType == WEAPONTYPE_CHAINSAW) + victimPed->ApplyMoveForce(posOffset.x*-1.0f, posOffset.y*-1.0f, 1.0f); + else + victimPed->ApplyMoveForce(posOffset.x*-5.0f, posOffset.y*-5.0f, 3.0f); } m_eWeaponState = WEAPONSTATE_MELEE_MADECONTACT; - if ( victimPed->m_nPedType == PEDTYPE_COP ) - CEventList::RegisterEvent(EVENT_ASSAULT_POLICE, EVENT_ENTITY_PED, victimPed, shooterPed, 2000); - else - CEventList::RegisterEvent(EVENT_ASSAULT, EVENT_ENTITY_PED, victimPed, shooterPed, 2000); + if (m_eWeaponType != WEAPONTYPE_KNIFE && m_eWeaponType != WEAPONTYPE_MACHETE + && m_eWeaponType != WEAPONTYPE_KATANA && m_eWeaponType != WEAPONTYPE_CHAINSAW) { + + if (victimPed->m_nPedType == PEDTYPE_COP) + CEventList::RegisterEvent(EVENT_ASSAULT_POLICE, EVENT_ENTITY_PED, victimPed, shooterPed, 2000); + else + CEventList::RegisterEvent(EVENT_ASSAULT, EVENT_ENTITY_PED, victimPed, shooterPed, 2000); + } else { + if (victimPed->m_nPedType == PEDTYPE_COP) + CEventList::RegisterEvent(EVENT_ASSAULT_NASTYWEAPON_POLICE, EVENT_ENTITY_PED, victimPed, shooterPed, 2000); + else + CEventList::RegisterEvent(EVENT_ASSAULT_NASTYWEAPON, EVENT_ENTITY_PED, victimPed, shooterPed, 2000); + } } } } } } } + CVehicle *nearVeh = (CVehicle*)CWorld::TestSphereAgainstWorld(fireSource, info->m_fRadius, nil, false, true, false, false, false, false); + if (nearVeh && nearVeh->IsCar()) + { + CAutomobile *nearCar = (CAutomobile*)nearVeh; + m_eWeaponState = WEAPONSTATE_MELEE_MADECONTACT; + if (shooterPed == FindPlayerPed()) + { + if (nearCar->IsLawEnforcementVehicle()) + { + FindPlayerPed()->SetWantedLevelNoDrop(1); + } + CEventList::RegisterEvent(EVENT_ASSAULT, EVENT_ENTITY_VEHICLE, nearCar, shooterPed, 2000); + } + float oldHealth = nearCar->m_fHealth; + if (m_eWeaponType == WEAPONTYPE_CHAINSAW) + { + for(int i=0; i<4; i++) { + CParticle::AddParticle(PARTICLE_SPARK_SMALL, gaTempSphereColPoints[0].point, CVector(0.0f, 0.0f, 0.3f)); + CParticle::AddParticle(PARTICLE_SPARK, gaTempSphereColPoints[0].point, gaTempSphereColPoints[0].normal * 0.1f); + } + } + if (m_eWeaponType == WEAPONTYPE_CHAINSAW) + { + nearCar->VehicleDamage(info->m_nDamage * (0.00075f * nearCar->pHandling->fMass), gaTempSphereColPoints[0].pieceB); + + // TODO(Miami): Particle not in III + // CParticle::AddParticle(81, gaTempSphereColPoints[0].point, CVector(0.0f, 0.0f, 0.0f), 0, 0.0f, 0, 0, 0, 0); + } + else + { + nearCar->VehicleDamage(info->m_nDamage* (0.00075f * nearCar->pHandling->fMass), gaTempSphereColPoints[0].pieceB); + } + if (nearCar->m_fHealth < oldHealth) + { + nearCar->m_nLastWeaponDamage = m_eWeaponType; + nearCar->m_pLastDamageEntity = shooterPed; + } + if (shooterPed->m_fDamageImpulse == 0.0f) + { + shooterPed->m_pDamageEntity = nearCar; + nearCar->RegisterReference(&shooterPed->m_pDamageEntity); + } + damageEntityRegistered = 2; + if (FindPlayerPed()->GetWeapon() == this && nearCar->VehicleCreatedBy != MISSION_VEHICLE) + { + if (nearCar->AutoPilot.m_nDrivingStyle != DRIVINGSTYLE_PLOUGH_THROUGH + && (CGeneral::GetRandomTrueFalse() || nearCar->AutoPilot.m_nCarMission != MISSION_CRUISE)) + { + int leaveCarDelay = 200; + CPed *driver = nearCar->pDriver; + if (driver && driver->CharCreatedBy != MISSION_CHAR) + { + if (driver->m_pedStats->m_temper <= driver->m_pedStats->m_fear) + { + driver->SetObjective(OBJECTIVE_FLEE_TILL_SAFE); + } + else + { + driver->SetObjective(OBJECTIVE_KILL_CHAR_ON_FOOT, FindPlayerPed()); + driver->m_objectiveTimer = CTimer::GetTimeInMilliseconds() + 10000; + driver->m_prevObjective = OBJECTIVE_KILL_CHAR_ON_FOOT; + } + driver->m_leaveCarTimer = CTimer::GetTimeInMilliseconds() + 200; + leaveCarDelay = 400; + } + for (int j = 0; j < nearCar->m_nNumPassengers; ++j) + { + CPed *passenger = nearCar->pPassengers[j]; + if (passenger && passenger->CharCreatedBy != MISSION_CHAR) + { + nearCar->pPassengers[j]->SetObjective(OBJECTIVE_FLEE_TILL_SAFE); + passenger->m_leaveCarTimer = CTimer::GetTimeInMilliseconds() + leaveCarDelay; + leaveCarDelay += 200; + } + } + } + else + { + CPed *driver = nearCar->pDriver; + if (driver) + { + if (driver->m_objective != OBJECTIVE_LEAVE_VEHICLE && driver->m_objective != OBJECTIVE_KILL_CHAR_ON_FOOT && + driver->m_objective != OBJECTIVE_FLEE_TILL_SAFE) + { + if (nearCar->AutoPilot.m_nDrivingStyle != DRIVINGSTYLE_PLOUGH_THROUGH) + nearCar->AutoPilot.m_nCruiseSpeed = nearCar->AutoPilot.m_nCruiseSpeed * 1.5f; + + nearCar->AutoPilot.m_nDrivingStyle = DRIVINGSTYLE_PLOUGH_THROUGH; + } + } + } + } + } + if (m_eWeaponType == WEAPONTYPE_CHAINSAW) + { + CEntity *nearStatic = (CObject*)CWorld::TestSphereAgainstWorld(fireSource, info->m_fRadius, nil, true, false, false, true, false, false); + if (nearStatic) + { + for(int i=0; i < 4; i++) { + CParticle::AddParticle(PARTICLE_SPARK_SMALL, gaTempSphereColPoints[0].point, CVector(0.0f, 0.0f, 0.3f), 0, 0.0f, 0, 0, 0, 0); + CParticle::AddParticle(PARTICLE_SPARK, gaTempSphereColPoints[0].point, 0.1f * gaTempSphereColPoints[0].normal, 0, 0.0f, 0, 0, 0, 0); + } + + // TODO(Miami): Particle not in III + //CParticle::AddParticle(81, gaTempSphereColPoints[0].point, CVector(0.0f, 0.0f, 0.0f), 0, 0.0f, 0, 0, 0, 0); + + if (!damageEntityRegistered) + { + m_eWeaponState = WEAPONSTATE_MELEE_MADECONTACT; + if (shooterPed->m_fDamageImpulse == 0.0f) + { + shooterPed->m_pDamageEntity = nearStatic; + nearStatic->RegisterReference(&shooterPed->m_pDamageEntity); + } + } + if (nearStatic->IsObject() && ((CObject*)nearStatic)->m_nCollisionDamageEffect >= DAMAGE_EFFECT_SMASH_COMPLETELY) + ((CObject*)nearStatic)->ObjectDamage(200.0f); + } + } return true; } @@ -564,7 +817,7 @@ CWeapon::FireInstantHit(CEntity *shooter, CVector *fireSource) CPed *threatAttack = (CPed*)shooterPed->m_pPointGunAt; if ( threatAttack->IsPed() ) { - threatAttack->m_pedIK.GetComponentPosition(target, PED_MID); + threatAttack->m_pedIK.GetComponentPosition(*(RwV3d *)&target, PED_MID); threatAttack->ReactToPointGun(shooter); } else @@ -606,7 +859,7 @@ CWeapon::FireInstantHit(CEntity *shooter, CVector *fireSource) CWorld::bIncludeDeadPeds = false; int32 rotSpeed = 1; - if ( m_eWeaponType == WEAPONTYPE_M16 ) + if ( m_eWeaponType == WEAPONTYPE_M4 ) rotSpeed = 4; CVector bulletPos; @@ -634,7 +887,7 @@ CWeapon::FireInstantHit(CEntity *shooter, CVector *fireSource) ProcessLineOfSight(*fireSource, target, point, victim, m_eWeaponType, shooter, true, true, true, true, true, true, false); int32 rotSpeed = 1; - if ( m_eWeaponType == WEAPONTYPE_M16 ) + if ( m_eWeaponType == WEAPONTYPE_M4 ) rotSpeed = 4; CVector bulletPos; @@ -659,45 +912,15 @@ CWeapon::FireInstantHit(CEntity *shooter, CVector *fireSource) switch ( m_eWeaponType ) { - case WEAPONTYPE_AK47: + case WEAPONTYPE_M4: + case WEAPONTYPE_RUGER: + case WEAPONTYPE_M60: + case WEAPONTYPE_MINIGUN: + case WEAPONTYPE_HELICANNON: { static uint8 counter = 0; - if ( !(++counter & 1) ) - { - CPointLights::AddLight(CPointLights::LIGHT_POINT, - *fireSource, CVector(0.0f, 0.0f, 0.0f), 5.0f, - 1.0f, 0.8f, 0.0f, CPointLights::FOG_NONE, false); - - CVector gunflashPos = *fireSource; - gunflashPos += CVector(0.06f*ahead.x, 0.06f*ahead.y, 0.0f); - CParticle::AddParticle(PARTICLE_GUNFLASH_NOANIM, gunflashPos, CVector(0.0f, 0.0f, 0.0f), nil, 0.10f); - gunflashPos += CVector(0.06f*ahead.x, 0.06f*ahead.y, 0.0f); - CParticle::AddParticle(PARTICLE_GUNFLASH_NOANIM, gunflashPos, CVector(0.0f, 0.0f, 0.0f), nil, 0.08f); - gunflashPos += CVector(0.05f*ahead.x, 0.05f*ahead.y, 0.0f); - CParticle::AddParticle(PARTICLE_GUNFLASH_NOANIM, gunflashPos, CVector(0.0f, 0.0f, 0.0f), nil, 0.06f); - gunflashPos += CVector(0.04f*ahead.x, 0.04f*ahead.y, 0.0f); - CParticle::AddParticle(PARTICLE_GUNFLASH_NOANIM, gunflashPos, CVector(0.0f, 0.0f, 0.0f), nil, 0.04f); - - CVector gunsmokePos = *fireSource; - float rnd = CGeneral::GetRandomNumberInRange(0.05f, 0.25f); - CParticle::AddParticle(PARTICLE_GUNSMOKE2, gunsmokePos, CVector(ahead.x*rnd, ahead.y*rnd, 0.0f)); - - CVector gunshellPos = *fireSource; - gunshellPos -= CVector(0.5f*ahead.x, 0.5f*ahead.y, 0.0f); - CVector dir = CrossProduct(CVector(ahead.x, ahead.y, 0.0f), CVector(0.0f, 0.0f, 5.0f)); - dir.Normalise2D(); - AddGunshell(shooter, gunshellPos, CVector2D(dir.x, dir.y), 0.018f); - } - - break; - } - - case WEAPONTYPE_M16: - { - static uint8 counter = 0; - - if ( !(++counter & 1) ) + if ( info->m_nFiringRate >= 50 && !(++counter & 1) ) { CPointLights::AddLight(CPointLights::LIGHT_POINT, *fireSource, CVector(0.0f, 0.0f, 0.0f), 5.0f, @@ -805,6 +1028,9 @@ CWeapon::FireInstantHit(CEntity *shooter, CVector *fireSource) } case WEAPONTYPE_COLT45: + case WEAPONTYPE_PYTHON: + case WEAPONTYPE_SNIPERRIFLE: + case WEAPONTYPE_LASERSCOPE: { CPointLights::AddLight(CPointLights::LIGHT_POINT, *fireSource, CVector(0.0f, 0.0f, 0.0f), 5.0f, @@ -918,7 +1144,8 @@ CWeapon::DoBulletImpact(CEntity *shooter, CEntity *victim, } else { - if ( m_eWeaponType == WEAPONTYPE_SHOTGUN || m_eWeaponType == WEAPONTYPE_HELICANNON ) + if ( IsShotgun(m_eWeaponType) || m_eWeaponType == WEAPONTYPE_HELICANNON + || m_eWeaponType == WEAPONTYPE_M60 || m_eWeaponType == WEAPONTYPE_PYTHON) { posOffset.Normalise(); victimPed->bIsStanding = false; @@ -943,7 +1170,7 @@ CWeapon::DoBulletImpact(CEntity *shooter, CEntity *victim, asoc->blendAmount = 0.0f; asoc->blendDelta = 8.0f; - if ( m_eWeaponType == WEAPONTYPE_AK47 || m_eWeaponType == WEAPONTYPE_M16 ) + if ( m_eWeaponType == WEAPONTYPE_M4 ) victimPlayer->m_nHitAnimDelayTimer = CTimer::GetTimeInMilliseconds() + 2500; else victimPlayer->m_nHitAnimDelayTimer = CTimer::GetTimeInMilliseconds() + 1000; @@ -972,7 +1199,7 @@ CWeapon::DoBulletImpact(CEntity *shooter, CEntity *victim, if ( CGame::nastyGame ) { uint8 bloodAmount = 8; - if ( m_eWeaponType == WEAPONTYPE_SHOTGUN || m_eWeaponType == WEAPONTYPE_HELICANNON ) + if ( IsShotgun(m_eWeaponType) || m_eWeaponType == WEAPONTYPE_HELICANNON ) bloodAmount = 32; CVector dir = (point->point - victim->GetPosition()) * 0.01f; @@ -1044,7 +1271,7 @@ CWeapon::DoBulletImpact(CEntity *shooter, CEntity *victim, } case ENTITY_TYPE_VEHICLE: { - ((CVehicle *)victim)->InflictDamage(shooter, m_eWeaponType, info->m_nDamage); + ((CVehicle *)victim)->InflictDamage(shooter, m_eWeaponType, info->m_nDamage, point->point); for ( int32 i = 0; i < 16; i++ ) CParticle::AddParticle(PARTICLE_SPARK, point->point, point->normal*0.05f); @@ -1188,10 +1415,35 @@ CWeapon::FireShotgun(CEntity *shooter, CVector *fireSource) else shooterAngle = RADTODEG(shooter->GetForward().Heading()); + int shootsAtOnce; + int checkObstacleOnShootNo; + float angleRange; + switch (m_eWeaponType) { + case WEAPONTYPE_SHOTGUN: + angleRange = DEGTORAD(9.0f); + checkObstacleOnShootNo = 1; + shootsAtOnce = 3; + break; + case WEAPONTYPE_SPAS12_SHOTGUN: + angleRange = DEGTORAD(6.0f); + checkObstacleOnShootNo = 1; + shootsAtOnce = 3; + break; + case WEAPONTYPE_STUBBY_SHOTGUN: + angleRange = DEGTORAD(18.0f); + checkObstacleOnShootNo = 2; + shootsAtOnce = 5; + break; + default: + break; + } + bool statUpdated = false; + float halfAngleRange = angleRange / 2.f; + float angleBetweenTwoShot = angleRange / (shootsAtOnce - 1.f); - for ( int32 i = 0; i < 5; i++ ) // five shoots at once + for ( int32 i = 0; i < shootsAtOnce; i++ ) { - float shootAngle = DEGTORAD(7.5f*i + shooterAngle - 15.0f); + float shootAngle = DEGTORAD(RADTODEG(halfAngleRange - angleBetweenTwoShot * i) + shooterAngle); CVector2D shootRot(-Sin(shootAngle), Cos(shootAngle)); CVector source, target; @@ -1203,12 +1455,17 @@ CWeapon::FireShotgun(CEntity *shooter, CVector *fireSource) TheCamera.Find3rdPersonCamTargetVector(1.0f, *fireSource, source, target); CVector Left = CrossProduct(TheCamera.Cams[TheCamera.ActiveCam].Front, TheCamera.Cams[TheCamera.ActiveCam].Up); - float f = float(i - 2) * (DEGTORAD(7.5f) / 2); + float f = (i - (shootsAtOnce / 2)) * angleBetweenTwoShot; target = f * Left + target - source; target *= info->m_fRange; target += source; + CWorld::bIncludeDeadPeds = true; + //bProcessVehicleWheels = true; // TODO(Miami): bProcessVehicleWheels + //bProcessPedsOnBoatsAndBikes = true; // TODO(Miami): bProcessPedsOnBoatsAndBikes - ProcessLineOfSight(source, target, point, victim, m_eWeaponType, shooter, true, true, true, true, true, true, false); + ProcessLineOfSight(source, target, point, victim, m_eWeaponType, shooter, true, true, true, true, true, false, false); // TODO(Miami): New parameter: ,true); + CWorld::bIncludeDeadPeds = false; + //bProcessVehicleWheels = false; // TODO(Miami): bProcessVehicleWheels } else { @@ -1224,24 +1481,84 @@ CWeapon::FireShotgun(CEntity *shooter, CVector *fireSource) DoDoomAiming(shooter, fireSource, &target); else { - float distToTarget = (shooterPed->m_pPointGunAt->GetPosition() - (*fireSource)).Magnitude2D(); - target.z += info->m_fRange / distToTarget * (shooterPed->m_pPointGunAt->GetPosition().z - target.z); + CVector pos; + if (shooterPed->m_pPointGunAt->IsPed()) { + ((CPed*)shooterPed->m_pPointGunAt)->m_pedIK.GetComponentPosition(*(RwV3d *)&pos, PED_MID); + } else { + pos = ((CPed*)shooterPed->m_pPointGunAt)->GetPosition(); + } + + float distToTarget = (pos - (*fireSource)).Magnitude2D(); + target.z += info->m_fRange / distToTarget * (pos.z - target.z); } } + if (shooter == FindPlayerPed()) + CWorld::bIncludeDeadPeds = true; - ProcessLineOfSight(*fireSource, target, point, victim, m_eWeaponType, shooter, true, true, true, true, true, true, false); + //bProcessPedsOnBoatsAndBikes = true; // TODO(Miami): bProcessPedsOnBoatsAndBikes + ProcessLineOfSight(*fireSource, target, point, victim, m_eWeaponType, shooter, true, true, true, true, true, false, false); // TODO(Miami): New parameter: ,true); + CWorld::bIncludeDeadPeds = false; } + //bProcessPedsOnBoatsAndBikes = false; // TODO(Miami): bProcessPedsOnBoatsAndBikes if ( victim ) { CGlass::WasGlassHitByBullet(victim, point.point); + CWeapon::BlowUpExplosiveThings(victim); + if (i == checkObstacleOnShootNo) + { + if (shooter) + { + if (shooter->IsPed() && !((CPed*)shooter)->IsPlayer()) + { + CPed *shooterPed = (CPed*)shooter; + CEntity *guyWePointGun = shooterPed->m_pPointGunAt; + if (guyWePointGun) + { + if (victim != guyWePointGun) + { + float distWithAim = (guyWePointGun->GetPosition() - shooter->GetPosition()).Magnitude(); + float distWithBullet = (point.point - shooter->GetPosition()).Magnitude(); + if (distWithAim > 0.1f && distWithBullet > 0.1f) + { + // Normalize + CVector aimDir = (guyWePointGun->GetPosition() - shooter->GetPosition()) * (1.0f / distWithAim); + CVector bulletDir = (point.point - shooter->GetPosition()) * (1.0f / distWithBullet); + float dotProd = DotProduct(aimDir, bulletDir); + float aimAndBulletAngle; + if (dotProd <= 0.35f) + aimAndBulletAngle = PI; + else + aimAndBulletAngle = Acos(dotProd); + + if (aimAndBulletAngle <= DEGTORAD(45.0f) && (aimAndBulletAngle <= DEGTORAD(15.0f) || distWithBullet / distWithAim >= 0.75f) && distWithBullet / distWithAim >= 0.99f) + { + shooterPed->bObstacleShowedUpDuringKillObjective = false; + shooterPed->m_shotTime = 0; + } + else + { + shooterPed->bObstacleShowedUpDuringKillObjective = true; + shooterPed->m_shootTimer = 0; + shooterPed->m_shotTime = CTimer::GetTimeInMilliseconds(); + if (distWithAim >= 10.0f) + shooterPed->SetAttackTimer(3000); + else + shooterPed->SetAttackTimer(1500); + } + } + } + } + } + } + } CBulletTraces::AddTrace(fireSource, &point.point); if ( victim->IsPed() ) { CPed *victimPed = (CPed *)victim; - if ( !victimPed->OnGround() && victim != shooter && victimPed->DoesLOSBulletHitPed(point) ) + if ( !victimPed->DyingOrDead() && victim != shooter ) { bool cantStandup = true; @@ -1254,7 +1571,8 @@ CWeapon::FireShotgun(CEntity *shooter, CVector *fireSource) posOffset.Normalise(); - if ( victimPed->m_getUpTimer > (CTimer::GetTimeInMilliseconds() - 3000) ) + if ( victimPed->m_getUpTimer > (CTimer::GetTimeInMilliseconds() - 3000) || + !victimPed->bCanBeShotInVehicle) cantStandup = false; if ( victimPed->bIsStanding && cantStandup ) @@ -1279,7 +1597,7 @@ CWeapon::FireShotgun(CEntity *shooter, CVector *fireSource) if ( CGame::nastyGame ) { uint8 bloodAmount = 8; - if ( m_eWeaponType == WEAPONTYPE_SHOTGUN ) + if ( IsShotgun(m_eWeaponType) ) bloodAmount = 32; CVector dir = (point.point - victim->GetPosition()) * 0.01f; @@ -1291,6 +1609,36 @@ CWeapon::FireShotgun(CEntity *shooter, CVector *fireSource) CParticle::AddParticle(PARTICLE_BLOOD_SMALL, point.point, dir); } } + } else { + if (CGame::nastyGame) + { + CVector dir = (point.point - victim->GetPosition()) * 0.01f; + dir.z = 0.01f; + + if (victimPed->GetIsOnScreen()) + { + for (uint8 i = 0; i < 8; i++) + CParticle::AddParticle(PARTICLE_BLOOD_SMALL, point.point + CVector(0.0f, 0.0f, 0.15f), dir); + } + if (victimPed->Dead()) + { + CAnimBlendAssociation *hitAssoc; + if (RpAnimBlendClumpGetFirstAssociation(victimPed->GetClump(), ASSOC_FRONTAL)) + { + hitAssoc = CAnimManager::BlendAnimation(victimPed->GetClump(), ASSOCGRP_STD, ANIM_FLOOR_HIT_F, 8.0f); + } + else + { + hitAssoc = CAnimManager::BlendAnimation(victimPed->GetClump(), ASSOCGRP_STD, ANIM_FLOOR_HIT, 8.0f); + } + if (hitAssoc) + { + hitAssoc->SetCurrentTime(0.0f); + hitAssoc->SetRun(); + hitAssoc->flags &= ~ASSOC_DELETEFADEDOUT; + } + } + } } } else @@ -1299,21 +1647,29 @@ CWeapon::FireShotgun(CEntity *shooter, CVector *fireSource) { case ENTITY_TYPE_VEHICLE: { - ((CVehicle *)victim)->InflictDamage(shooter, m_eWeaponType, info->m_nDamage); + if (point.pieceB >= SURFACE_LAMP_POST && point.pieceB <= SURFACE_METAL_CHAIN_FENCE) { + ((CVehicle*)victim)->BurstTyre(point.pieceB, true); - for ( int32 i = 0; i < 16; i++ ) - CParticle::AddParticle(PARTICLE_SPARK, point.point, point.normal*0.05f); + for (int32 i = 0; i < 4; i++) + CParticle::AddParticle(PARTICLE_BULLETHIT_SMOKE, point.point, point.normal * 0.05f); + } + else + { + ((CVehicle*)victim)->InflictDamage(shooter, m_eWeaponType, info->m_nDamage); + + for (int32 i = 0; i < 16; i++) + CParticle::AddParticle(PARTICLE_SPARK, point.point, point.normal * 0.05f); #ifndef FIX_BUGS - CVector dist = point.point - (*fireSource); - CVector offset = dist - Max(0.2f*dist.Magnitude(), 2.0f) * CVector(shootRot.x, shootRot.y, 0.0f); - CVector smokePos = *fireSource + offset; + CVector dist = point.point - (*fireSource); + CVector offset = dist - Max(0.2f * dist.Magnitude(), 2.0f) * CVector(shootRot.x, shootRot.y, 0.0f); + CVector smokePos = *fireSource + offset; #else - CVector smokePos = point.point; + CVector smokePos = point.point; #endif - CParticle::AddParticle(PARTICLE_BULLETHIT_SMOKE, smokePos, CVector(0.0f, 0.0f, 0.0f)); - + CParticle::AddParticle(PARTICLE_BULLETHIT_SMOKE, smokePos, CVector(0.0f, 0.0f, 0.0f)); + } break; } @@ -1343,13 +1699,15 @@ CWeapon::FireShotgun(CEntity *shooter, CVector *fireSource) if ( !victimObject->bInfiniteMass ) { - if ( victimObject->IsStatic() && victimObject->m_fUprootLimit <= 0.0f ) + bool notStatic = !victimObject->IsStatic(); + if ( notStatic && victimObject->m_fUprootLimit <= 0.0f ) { victimObject->bIsStatic = false; victimObject->AddToMovingList(); } - if ( !victimObject->IsStatic()) + notStatic = !victimObject->IsStatic(); + if ( !notStatic ) { CVector moveForce = point.normal*-5.0f; victimObject->ApplyMoveForce(moveForce.x, moveForce.y, moveForce.z); @@ -1372,17 +1730,29 @@ CWeapon::FireShotgun(CEntity *shooter, CVector *fireSource) } case ENTITY_TYPE_VEHICLE: { + if (!statUpdated) { + //CStats::NumBulletsHit++; // TODO(Miami): Stats + statUpdated = true; + } DMAudio.PlayOneShot(((CPhysical*)victim)->m_audioEntityId, SOUND_WEAPON_HIT_VEHICLE, 1.0f); break; } case ENTITY_TYPE_PED: { + if (!statUpdated) { + //CStats::NumBulletsHit++; // TODO(Miami): Stats + statUpdated = true; + } DMAudio.PlayOneShot(((CPhysical*)victim)->m_audioEntityId, SOUND_WEAPON_HIT_PED, 1.0f); ((CPed*)victim)->Say(SOUND_PED_BULLET_HIT); break; } case ENTITY_TYPE_OBJECT: { + if (!statUpdated) { + //CStats::NumBulletsHit++; // TODO(Miami): Stats + statUpdated = true; + } PlayOneShotScriptObject(SCRIPT_SOUND_BULLET_HIT_GROUND_2, point.point); break; } @@ -1631,8 +2001,7 @@ CWeapon::FireM16_1stPerson(CEntity *shooter) CVector bulletPos; - // TODO(Miami): M60 - if ( CHeli::TestBulletCollision(&source, &target, &bulletPos, (/*m_eWeaponType == WEAPONTYPE_M60 || */ m_eWeaponType == WEAPONTYPE_HELICANNON ? 20 : 4)) ) + if ( CHeli::TestBulletCollision(&source, &target, &bulletPos, (m_eWeaponType == WEAPONTYPE_M60 || m_eWeaponType == WEAPONTYPE_HELICANNON ? 20 : 4)) ) { for ( int32 i = 0; i < 16; i++ ) CParticle::AddParticle(PARTICLE_SPARK, bulletPos, CVector(0.0f, 0.0f, 0.0f)); @@ -1642,15 +2011,14 @@ CWeapon::FireM16_1stPerson(CEntity *shooter) { CPad::GetPad(0)->StartShake_Distance(240, 128, FindPlayerPed()->GetPosition().x, FindPlayerPed()->GetPosition().y, FindPlayerPed()->GetPosition().z); - // TODO(Miami) float mult; switch (m_eWeaponType) { - case WEAPONTYPE_M16: // case WEAPONTYPE_M4: + case WEAPONTYPE_M4: case WEAPONTYPE_HELICANNON: - // case WEAPONTYPE_M60: + case WEAPONTYPE_M60: mult = 0.0003f; break; - case WEAPONTYPE_AK47: // case WEAPONTYPE_RUGER: + case WEAPONTYPE_RUGER: mult = 0.00015f; break; default: @@ -1669,7 +2037,7 @@ CWeapon::FireM16_1stPerson(CEntity *shooter) } bool -CWeapon::FireInstantHitFromCar(CAutomobile *shooter, bool left) +CWeapon::FireInstantHitFromCar(CVehicle *shooter, bool left) { CWeaponInfo *info = GetInfo(); @@ -2040,8 +2408,10 @@ CWeapon::Reload(void) } void -CWeapon::Update(int32 audioEntity) +CWeapon::Update(int32 audioEntity, CPed *pedToAdjustSound) { + CWeaponInfo *info = GetInfo(); + switch ( m_eWeaponState ) { case WEAPONSTATE_MELEE_MADECONTACT: @@ -2052,9 +2422,9 @@ CWeapon::Update(int32 audioEntity) case WEAPONSTATE_FIRING: { - if ( m_eWeaponType == WEAPONTYPE_SHOTGUN && AEHANDLE_IS_OK(audioEntity) ) + if ( IsShotgun(m_eWeaponType) && AEHANDLE_IS_OK(audioEntity) ) { - uint32 timePassed = m_nTimer - gReloadSampleTime[WEAPONTYPE_SHOTGUN]; + uint32 timePassed = m_nTimer - gReloadSampleTime[m_eWeaponType]; if ( CTimer::GetPreviousTimeInMilliseconds() < timePassed && CTimer::GetTimeInMilliseconds() >= timePassed ) DMAudio.PlayOneShot(audioEntity, SOUND_WEAPON_RELOAD, 0.0f); } @@ -2072,11 +2442,59 @@ CWeapon::Update(int32 audioEntity) case WEAPONSTATE_RELOADING: { - if ( AEHANDLE_IS_OK(audioEntity) && m_eWeaponType < WEAPONTYPE_LAST_WEAPONTYPE ) + if ( AEHANDLE_IS_OK(audioEntity) && m_eWeaponType < WEAPONTYPE_TOTALWEAPONS) { - uint32 timePassed = m_nTimer - gReloadSampleTime[m_eWeaponType]; - if ( CTimer::GetPreviousTimeInMilliseconds() < timePassed && CTimer::GetTimeInMilliseconds() >= timePassed ) - DMAudio.PlayOneShot(audioEntity, SOUND_WEAPON_RELOAD, 0.0f); + CAnimBlendAssociation *reloadAssoc = nil; + if (pedToAdjustSound) { + if (CPed::GetReloadAnim(info) && (!CWorld::Players[CWorld::PlayerInFocus].m_bFastReload || !pedToAdjustSound->IsPlayer())) { + reloadAssoc = RpAnimBlendClumpGetAssociation(pedToAdjustSound->GetClump(), CPed::GetReloadAnim(info)); + if (!reloadAssoc) { + reloadAssoc = RpAnimBlendClumpGetAssociation(pedToAdjustSound->GetClump(), CPed::GetCrouchReloadAnim(info)); + } + } + } + if (reloadAssoc && reloadAssoc->IsRunning() && reloadAssoc->blendAmount > 0.2f) { + float soundStart = 0.75f; + switch (info->m_AnimToPlay) { + case ASSOCGRP_PYTHON: + soundStart = 0.5f; + break; + case ASSOCGRP_COLT: + case ASSOCGRP_TEC: + soundStart = 0.7f; + break; + case ASSOCGRP_UZI: + soundStart = 0.75f; + break; + case ASSOCGRP_RIFLE: + soundStart = 0.75f; + break; + case ASSOCGRP_M60: + soundStart = 0.7f; + break; + default: + break; + } + if (reloadAssoc->GetProgress() >= soundStart && (reloadAssoc->currentTime - reloadAssoc->timeStep) / reloadAssoc->hierarchy->totalLength < soundStart) { +#ifdef AUDIO_NOT_READY + DMAudio.PlayOneShot(audioEntity, SOUND_WEAPON_RELOAD, 0.0f); +#else + DMAudio.PlayOneShot(audioEntity, SOUND_WEAPON_RELOAD, m_eWeaponType); +#endif + } + if (CTimer::GetTimeInMilliseconds() > m_nTimer && reloadAssoc->GetProgress() < 0.9f) { + m_nTimer = CTimer::GetTimeInMilliseconds(); + } + } else { + uint32 timePassed = m_nTimer - gReloadSampleTime[m_eWeaponType]; + if (CTimer::GetPreviousTimeInMilliseconds() < timePassed && CTimer::GetTimeInMilliseconds() >= timePassed) { +#ifdef AUDIO_NOT_READY + DMAudio.PlayOneShot(audioEntity, SOUND_WEAPON_RELOAD, 0.0f); +#else + DMAudio.PlayOneShot(audioEntity, SOUND_WEAPON_RELOAD, m_eWeaponType); +#endif + } + } } if ( CTimer::GetTimeInMilliseconds() > m_nTimer ) @@ -2199,13 +2617,15 @@ FireOneInstantHitRound(CVector *source, CVector *target, int32 damage) bool CWeapon::IsTypeMelee(void) { - return m_eWeaponType == WEAPONTYPE_UNARMED || m_eWeaponType == WEAPONTYPE_BASEBALLBAT; + return CWeaponInfo::GetWeaponInfo(m_eWeaponType)->m_eWeaponFire == WEAPON_FIRE_MELEE; } bool CWeapon::IsType2Handed(void) { - return m_eWeaponType >= WEAPONTYPE_SHOTGUN && m_eWeaponType <= WEAPONTYPE_FLAMETHROWER && m_eWeaponType != WEAPONTYPE_ROCKETLAUNCHER; + return m_eWeaponType == WEAPONTYPE_FLAMETHROWER || m_eWeaponType == WEAPONTYPE_HELICANNON || m_eWeaponType == WEAPONTYPE_M60 || + m_eWeaponType == WEAPONTYPE_M4 || IsShotgun(m_eWeaponType) || + m_eWeaponType == WEAPONTYPE_RUGER || m_eWeaponType == WEAPONTYPE_SNIPERRIFLE || m_eWeaponType == WEAPONTYPE_LASERSCOPE; } void @@ -2312,13 +2732,15 @@ CWeapon::BlowUpExplosiveThings(CEntity *thing) bool CWeapon::HasWeaponAmmoToBeUsed(void) { - switch (m_eWeaponType) { - case WEAPONTYPE_UNARMED: - case WEAPONTYPE_BASEBALLBAT: - return true; - default: - return m_nAmmoTotal != 0; - } + // FIX: This is better (not bug tho) +#if 0 + if (m_eWeaponType <= WEAPONTYPE_CHAINSAW) +#else + if (CWeaponInfo::GetWeaponInfo(m_eWeaponType)->m_eWeaponFire == WEAPON_FIRE_MELEE) +#endif + return true; + else + return m_nAmmoTotal != 0; } bool diff --git a/src/weapons/Weapon.h b/src/weapons/Weapon.h index 32322da0..b4ed93c3 100644 --- a/src/weapons/Weapon.h +++ b/src/weapons/Weapon.h @@ -7,7 +7,8 @@ class CEntity; class CPhysical; -class CAutomobile; +class CVehicle; +class CPed; struct CColPoint; class CWeaponInfo; @@ -16,8 +17,8 @@ class CWeapon public: eWeaponType m_eWeaponType; eWeaponState m_eWeaponState; - uint32 m_nAmmoInClip; - uint32 m_nAmmoTotal; + int32 m_nAmmoInClip; + int32 m_nAmmoTotal; uint32 m_nTimer; bool m_bAddRotOffset; @@ -35,7 +36,7 @@ public: void Shutdown(); bool Fire (CEntity *shooter, CVector *fireSource); - bool FireFromCar (CAutomobile *shooter, bool left); + bool FireFromCar (CVehicle *shooter, bool left); bool FireMelee (CEntity *shooter, CVector &fireSource); bool FireInstantHit(CEntity *shooter, CVector *fireSource); @@ -50,14 +51,14 @@ public: bool FireAreaEffect (CEntity *shooter, CVector *fireSource); bool FireSniper (CEntity *shooter); bool FireM16_1stPerson (CEntity *shooter); - bool FireInstantHitFromCar(CAutomobile *shooter, bool left); + bool FireInstantHitFromCar(CVehicle *shooter, bool left); static void DoDoomAiming (CEntity *shooter, CVector *source, CVector *target); static void DoTankDoomAiming (CEntity *shooter, CEntity *driver, CVector *source, CVector *target); static void DoDriveByAutoAiming(CEntity *shooter, CVector *source, CVector *target); void Reload(void); - void Update(int32 audioEntity); + void Update(int32 audioEntity, CPed *pedToAdjustSound); bool IsTypeMelee (void); bool IsType2Handed(void); @@ -67,6 +68,8 @@ public: static void BlowUpExplosiveThings(CEntity *thing); bool HasWeaponAmmoToBeUsed(void); + static bool IsShotgun(int weapon) { return weapon == WEAPONTYPE_SHOTGUN || weapon == WEAPONTYPE_SPAS12_SHOTGUN || weapon == WEAPONTYPE_STUBBY_SHOTGUN; } + static bool ProcessLineOfSight(CVector const &point1, CVector const &point2, CColPoint &point, CEntity *&entity, eWeaponType type, CEntity *shooter, bool checkBuildings, bool checkVehicles, bool checkPeds, bool checkObjects, bool checkDummies, bool ignoreSeeThrough, bool ignoreSomeObjects); #ifdef COMPATIBLE_SAVES diff --git a/src/weapons/WeaponInfo.cpp b/src/weapons/WeaponInfo.cpp index 7128a04f..bd53d8c5 100644 --- a/src/weapons/WeaponInfo.cpp +++ b/src/weapons/WeaponInfo.cpp @@ -11,7 +11,8 @@ // Yeah... int32 CWeaponInfo::ms_aMaxAmmoForWeapon[WEAPONTYPE_TOTALWEAPONS] = { - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1 }; CWeaponInfo CWeaponInfo::ms_apWeaponInfos[WEAPONTYPE_TOTALWEAPONS]; @@ -19,28 +20,47 @@ CWeaponInfo CWeaponInfo::ms_apWeaponInfos[WEAPONTYPE_TOTALWEAPONS]; // --MIAMI: Todo static char ms_aWeaponNames[][32] = { "Unarmed", + "BrassKnuckle", + "ScrewDriver", + "GolfClub", + "NightStick", + "Knife", "BaseballBat", + "Hammer", + "Cleaver", + "Machete", + "Katana", + "Chainsaw", + "Grenade", + "DetonateGrenade", + "TearGas", + "Molotov", + "Rocket", "Colt45", + "Python", + "Shotgun", + "Spas12Shotgun", + "StubbyShotgun", "Tec9", "Uzi", "SilencedIngram", "Mp5", - "Shotgun", - "AK47", - "M16", + "m4", + "Ruger", "SniperRifle", + "LaserScope", "RocketLauncher", "FlameThrower", - "Molotov", - "Rocket", - "Grenade", - "DetonateGrenade", + "M60", + "Minigun", "Detonator", "HeliCannon", + "Camera", }; CWeaponInfo* -CWeaponInfo::GetWeaponInfo(eWeaponType weaponType) { +CWeaponInfo::GetWeaponInfo(eWeaponType weaponType) +{ return &CWeaponInfo::ms_apWeaponInfos[weaponType]; } @@ -61,8 +81,7 @@ CWeaponInfo::Initialise(void) ms_apWeaponInfos[i].m_fLifespan = 0.0f; ms_apWeaponInfos[i].m_fSpread = 0.0f; ms_apWeaponInfos[i].m_vecFireOffset = CVector(0.0f, 0.0f, 0.0f); - // TODO(Miami): ASSOCGRP_UNARMED - ms_apWeaponInfos[i].m_AnimToPlay = ASSOCGRP_STD; + ms_apWeaponInfos[i].m_AnimToPlay = ASSOCGRP_UNARMED; ms_apWeaponInfos[i].m_fAnimLoopStart = 0.0f; ms_apWeaponInfos[i].m_fAnimLoopEnd = 0.0f; ms_apWeaponInfos[i].m_fAnimFrameFire = 0.0f; @@ -214,9 +233,7 @@ CWeaponInfo::LoadWeaponData(void) ms_apWeaponInfos[weaponType].m_nWeaponSlot = weaponSlot; - // TODO(Miami): Enable once weapons are done - if (animLoopEnd < 98.0f && weaponType != WEAPONTYPE_FLAMETHROWER && weaponType != WEAPONTYPE_SHOTGUN - /*&& weaponType != 20 && weaponType != 21*/) + if (animLoopEnd < 98.0f && weaponType != WEAPONTYPE_FLAMETHROWER && !CWeapon::IsShotgun(weaponType)) ms_apWeaponInfos[weaponType].m_nFiringRate = ((ms_apWeaponInfos[weaponType].m_fAnimLoopEnd - ms_apWeaponInfos[weaponType].m_fAnimLoopStart) * 900.0f); if (weaponType == WEAPONTYPE_DETONATOR || weaponType == WEAPONTYPE_HELICANNON) @@ -254,6 +271,7 @@ CWeaponInfo::FindWeaponFireType(char *name) if (strcmp(name, "INSTANT_HIT") == 0) return WEAPON_FIRE_INSTANT_HIT; if (strcmp(name, "PROJECTILE") == 0) return WEAPON_FIRE_PROJECTILE; if (strcmp(name, "AREA_EFFECT") == 0) return WEAPON_FIRE_AREA_EFFECT; + if (strcmp(name, "CAMERA") == 0) return WEAPON_FIRE_CAMERA; Error("Unknown weapon fire type, WeaponInfo.cpp"); return WEAPON_FIRE_INSTANT_HIT; } diff --git a/src/weapons/WeaponInfo.h b/src/weapons/WeaponInfo.h index cb10f095..e7013004 100644 --- a/src/weapons/WeaponInfo.h +++ b/src/weapons/WeaponInfo.h @@ -1,5 +1,6 @@ #pragma once +#include "AnimManager.h" #include "AnimationId.h" #include "WeaponType.h" @@ -14,7 +15,7 @@ public: float m_fRange; uint32 m_nFiringRate; uint32 m_nReload; - uint32 m_nAmountofAmmunition; + int32 m_nAmountofAmmunition; uint32 m_nDamage; float m_fSpeed; float m_fRadius; diff --git a/src/weapons/WeaponType.h b/src/weapons/WeaponType.h index 61d03ad3..65d715ec 100644 --- a/src/weapons/WeaponType.h +++ b/src/weapons/WeaponType.h @@ -1,28 +1,46 @@ #pragma once -// --MIAMI: TODO enum eWeaponType { WEAPONTYPE_UNARMED, + WEAPONTYPE_BRASSKNUCKLE, + WEAPONTYPE_SCREWDRIVER, + WEAPONTYPE_GOLFCLUB, + WEAPONTYPE_NIGHTSTICK, + WEAPONTYPE_KNIFE, WEAPONTYPE_BASEBALLBAT, + WEAPONTYPE_HAMMER, + WEAPONTYPE_CLEAVER, + WEAPONTYPE_MACHETE, + WEAPONTYPE_KATANA, + WEAPONTYPE_CHAINSAW, + WEAPONTYPE_GRENADE, + WEAPONTYPE_DETONATOR_GRENADE, + WEAPONTYPE_TEARGAS, + WEAPONTYPE_MOLOTOV, + WEAPONTYPE_ROCKET, WEAPONTYPE_COLT45, + WEAPONTYPE_PYTHON, + WEAPONTYPE_SHOTGUN, + WEAPONTYPE_SPAS12_SHOTGUN, + WEAPONTYPE_STUBBY_SHOTGUN, WEAPONTYPE_TEC9, WEAPONTYPE_UZI, WEAPONTYPE_SILENCED_INGRAM, WEAPONTYPE_MP5, - WEAPONTYPE_SHOTGUN, - WEAPONTYPE_AK47, - WEAPONTYPE_M16, + WEAPONTYPE_M4, + WEAPONTYPE_RUGER, WEAPONTYPE_SNIPERRIFLE, + WEAPONTYPE_LASERSCOPE, WEAPONTYPE_ROCKETLAUNCHER, WEAPONTYPE_FLAMETHROWER, - WEAPONTYPE_MOLOTOV, - WEAPONTYPE_ROCKET, - WEAPONTYPE_GRENADE, - WEAPONTYPE_DETONATOR_GRENADE, + WEAPONTYPE_M60, + WEAPONTYPE_MINIGUN, WEAPONTYPE_DETONATOR, WEAPONTYPE_HELICANNON, - WEAPONTYPE_LAST_WEAPONTYPE, + WEAPONTYPE_CAMERA, + WEAPONTYPE_TOTALWEAPONS = 37, + WEAPONTYPE_HEALTH = 37, WEAPONTYPE_ARMOUR, WEAPONTYPE_RAMMEDBYCAR, WEAPONTYPE_RUNOVERBYCAR, @@ -31,8 +49,8 @@ enum eWeaponType WEAPONTYPE_DROWNING, WEAPONTYPE_FALL, WEAPONTYPE_UNIDENTIFIED, - - WEAPONTYPE_TOTALWEAPONS = WEAPONTYPE_LAST_WEAPONTYPE, + WEAPONTYPE_ANYMELEE, + WEAPONTYPE_ANYWEAPON }; enum { @@ -44,7 +62,7 @@ enum eWeaponFire { WEAPON_FIRE_INSTANT_HIT, WEAPON_FIRE_PROJECTILE, WEAPON_FIRE_AREA_EFFECT, - WEAPON_FIRE_USE + WEAPON_FIRE_CAMERA }; // Taken from MTA SA, seems it's unchanged